DataGridView 使用基于枚举的 Combobox 列链接到 DataTable [英] DataGridView linked to DataTable with Combobox column based on enum

查看:24
本文介绍了DataGridView 使用基于枚举的 Combobox 列链接到 DataTable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天花了很多时间搜索这个,我不得不放弃.

Having spent a lot of yesterday searching on this one I have to give up.

我有一个链接到数据表的 DataGridView.其中一列是枚举,我希望将其显示为组合框列.

I have a DataGridView linked to a Datatable. One of the columns is an enum and I want that to show as a Combobox column.

我找到了这个链接 创建下拉列表选项来自 DataGridView 中的枚举,它具有使用以下内容的答案...

I found this link Create drop down list options from enum in a DataGridView which has an answer of using the following...

    DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
    col.Name = "My Enum Column";
    col.DataSource = Enum.GetValues(typeof(MyEnum));
    col.ValueType = typeof(MyEnum);
    dataGridView1.Columns.Add(col);

我已经尝试过,但是当用户创建新记录时,从下拉列表中选择一个选项(显示正确的选项)然后移出字段,他们会收到消息DataGridViewComboBoxCel 值无效".我在搜索中找到了一些关于如何捕获此错误的解决方案,然后什么都不做(从而隐藏错误)但我想解决它而不仅仅是隐藏它.如果用户没问题,他们会再重复两次.

I've tried that but when the user creates a new record, chooses an option from the drop down (the correct options show) then moves off the field they get the message "DataGridViewComboBoxCel value is not valid". I've found some solutions in searching that talk about how to trap this error, then do nothing (thus hiding the error) but I want to solve it not just hide it. If the user OK's the message they get it repeat another two times.

我还看到了循环遍历枚举中的值并为每个值创建一个包含 int 和字符串的数据表的解决方案,然后使用该数据表作为组合上的数据源.过去在使用后端 MSSQL 数据库时,我曾使用数据表作为组合框的来源.

I've also seen solutions that loop through the values in the enum and create a datatable containing the int and the string for each one, then using the datatable as a datasource on the combo. I've used a datatable as the source for a combobox in the past when working with a back-end MSSQL database.

另一种变体是循环并直接写入组合中,例如...

Another variant of this is to loop through and write straight into the combo such as this...

    foreach (MyEnum bar in MyEnum.GetValues(typeof(MyEnum)))
    {
        string barName = MyEnum.GetName(typeof(MyEnum), bar);
        MyComboColumn.Items.Add(barName);
    }

例如在此链接中的问题中.如何向组合框添加一些枚举值

such as in the question in this link. How can I add some Enum values to a combobox

我的问题:是否可以使用 Enum.GetValues(typeof(MyEnum));方法?数据表方法似乎冗长乏味.循环然后使用 MyComboColumn.Items.Add(barName);也有点冗长,将导致枚举的字符串版本被记录在数据表中而不是整数(我宁愿它是整数).

MY QUESTION: Can it be made to work using the Enum.GetValues(typeof(MyEnum)); method? The datatable method seems long winded. The looping then using MyComboColumn.Items.Add(barName); is also somewhat long winded and will result in the string version of the enum being recorded in the datatable not the integer (and I would rather it was the integer).

我找不到 Enum.GetValues(typeof(MyEnum)) 方法的示例,其中网格链接到数据表.当我搜索它时,我只是遇到了其他方法.

I can't find examples of the Enum.GetValues(typeof(MyEnum)) method where the grid is linked to a datatable. When I search on that I just come across the other methods.

我认为问题很可能出在底层表列的数据类型上.我试过把它当作一个整数,一个字符串,我试过不定义它.我想不出还有什么可以尝试这种类型的.

I think the problem is likely to lie in the data type on the underlying table column. I've tried this as an integer, as a string and I've tried not defining it. I can't think what else to try on that type.

这是我的简化代码.(DVG 是我在表单上的 DataGridView).

Here is my simplified code. (DVG is my DataGridView on the form).

enum EngineType
{
    None = 0,
    EngineType1 = 1,
    EngineType2 = 2
}
public partial class MyClass : Form
{
    DataTable DtTbl;

    public MyClass()
    {
        InitializeComponent();
        CreateTableStructure();
    }

    private void CreateTableStructure()
    {
        DGV.AutoGenerateColumns = false;
        DGV.DataSource = DtTbl;

        DtTbl = new DataTable();

        DtTbl.Columns.Add(new DataColumn("Name", System.Type.GetType("System.String")));
        DataGridViewTextBoxColumn NameCol = new DataGridViewTextBoxColumn();
        NameCol.DataPropertyName = "Name";
        NameCol.HeaderText = "Name";
        DGV.Columns.Add(NameCol);

        DtTbl.Columns.Add(new DataColumn("Engine", System.Type.GetType("System.Int32")));
        DataGridViewComboBoxColumn EngineCol = new DataGridViewComboBoxColumn();
        EngineCol.DataPropertyName = "Engine";
        EngineCol.HeaderText = "Engine";
        //EngineCol.DataSource = EngineType.GetValues(typeof(EngineType));

        foreach (EngineType engine in EngineType.GetValues(typeof(EngineType)))
        {
            string engineName = EngineType.GetName(typeof(EngineType), engine);
            EngineCol.Items.Add(engineName);
        }


        DGV.Columns.Add(EngineCol);

    }
}

推荐答案

我放弃了将枚举直接链接到组合框的做法.我以为 Koryu 已经解决了它,但是当用户输入数据时它可以工作,如果我尝试以编程方式添加一行,并为枚举提供有效值,它仍然会给出错误.

I gave up on doing this linking the enum directly to the combox. I thought that Koryu had solved it but while it then worked when a user entered data, if I tried to programmatically add a row, with a valid value for the enum, it still gave the error.

基于我上面的代码,加上 Koryu 的改动,我添加了这样一行.

Based on my above code, with Koryu's change, I added a row like this.

private void CreateDefaultRows() 
{
  DataRow Row = DtTbl.NewRow();
  Row["Name"] = "FIN";
  Row["Engine"] = EngineType.EngineType1;
  DtTbl.Rows.Add(Row);
  DGV.DataSource = DtTbl;
}

但尽管进行了调试以确保有效值,但我仍然遇到错误.

But despite debugging to ensure a valid value I still got the error.

我是通过使用数据表的方法解决的.我在助手类中编写了一个通用方法,该方法返回任何枚举的数据表.

I solved it by using the method of using a datatable. I wrote a generic method in my helper class which returns a datatable for any enum.

    public static DataTable Enum2DataTable<T>()
    {
        DataTable EnumTable = new DataTable();
        EnumTable.Columns.Add(new DataColumn("Value", System.Type.GetType("System.Int32")));
        EnumTable.Columns.Add(new DataColumn("Display", System.Type.GetType("System.String")));
        DataRow EnumRow;
        foreach (T E in Enum.GetValues(typeof(T)))
        {
            EnumRow = EnumTable.NewRow();
            EnumRow["Value"] = E;
            EnumRow["Display"] = E.ToString();
            EnumTable.Rows.Add(EnumRow);
        }

        return EnumTable;
    }

如果我在问题的代码中定义组合框列时添加以下行,则一切正常,没有其他更改,也没有错误.

If I then add the following line when defining the combo box column in my code in the question everything works fine with no other changes and with no errors.

EngineCol.DataSource = Enum2DataTable<EngineType>();

虽然这行得通,而且我有一个可重复使用的方法来再次执行此操作,但仍然感觉应该可以将枚举直接分配给组合框,因为这几乎"有效.

While this works, and I have a reusable method to do this again, it still feels like it should have been possible assigning the enum directly to the combo box as that 'almost' works.

很想知道为什么它不起作用,但这个解决方案至少有效.

Would love to know why it doesn't work but this solution works at least.

这篇关于DataGridView 使用基于枚举的 Combobox 列链接到 DataTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆