如何在DataGridViewComboBox中显示枚举类型成员?

问题描述:

为了在此DatagridViewComboBox中显示ReadAccess枚举成员,还需要做些什么?如何在DataGridViewComboBox中显示枚举类型成员?

ReadDataGridViewComboBoxColumn.Items.Clear(); 
ReadDataGridViewComboBoxColumn.Items.AddRange(ReadAccess.None, ReadAccess.Allowed); 
ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess); 

这里是关于DataGridView的设计器生成的代码:

this.rolesDataGridView.AutoGenerateColumns = false; 
this.rolesDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 
this.TableNameDataGridViewTextBoxColumn, 
this.ReadDataGridViewComboBoxColumn, 
this.WriteDataGridViewComboBoxColumn, 
this.ReadCodeDataGridViewComboBoxColumn, 
this.ProcessDataGridViewCheckBoxColumn, 
this.AdministrateDataGridViewCheckBoxColumn}); 
this.rolesDataGridView.DataSource = this.bsTablePermissions;

终于,在InitializeComponent();后,我设置的DataGridView的DataSource:

this.rolesDataGridView.DataSource = this.RoleTablePermissions; // a bindingsource list
+0

你完成了'this.Controls.Add(ReadDataGridViewComboBoxColumn)'或类似吗? – 2010-11-08 02:41:01

+0

@George:是的,当然...但是当我运行该项目时,组合框被冻结,我无法打开它的列表... – 2010-11-08 02:44:49

+0

是否有更多的代码来实例化DataGridView比这只? – 2010-11-08 02:50:48

这是一个问题,我”我遇到过很多次了。 DataGridViewComboBoxColumn不知道如何协调枚举的字符串表示和其整数值之间的差异。即使您将ValueType设置为枚举类型,DataGridView也会尝试将单元格的值设置为基本的int值 - 这就是在数据绑定期间将引发FormatException的原因。

我发现克服这个问题的唯一方法就是将DataGridViewComboBoxColumn绑定到将字符串值与整数值分开的数据源。您可以使用匿名类型用于这一目的:

ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess); 
ReadDataGridViewComboBoxColumn.ValueMember = "Value"; 
ReadDataGridViewComboBoxColumn.DisplayMember = "Display"; 
ReadDataGridViewComboBoxColumn.DataSource = new ReadAccess[] 
    { ReadAccess.None, ReadAccess.Allowed } 
    .Select(value => new { Display=value.ToString(), Value=(int)value }) 
    .ToList(); 

这样,DataGridView知道如何与与其格式化值单元格的值。

+0

哇...真好!非常感谢... – 2010-11-08 16:29:36

+0

@Bradley:我仍然有这个问题...组合框仍然冻结,我不能打开列表,并且,我收到'FormatException' ... – 2010-11-08 18:03:49

+0

@Dr TJ:是否有可能你的'DataGridView'中的其他列之一导致了问题,现在你已经解决了这个问题?检查您的处理程序中的'ColumnIndex'属性是否存在DataError事件。 – 2010-11-08 23:05:47

添加到布拉德利·史密斯给出了答案:一是可以得到所有枚举值(而不是命名每个单独)轻松地使用此代码:

ReadDataGridViewComboBoxColumn.DataSource = 
     new List<ReadAccess>((ReadAccess[]) Enum.GetValues(typeof(ReadAccess))) 
     .Select(value => new { Display=value.ToString(), Value=(int)value }) 
     .ToList(); 

你应该枚举值不能转换成int类型。如果你有喜欢“无效值”的错误使用此代码:

ReadDataGridViewComboBoxColumn.DataSource = new ReadAccess[] 
{ ReadAccess.None, ReadAccess.Allowed } 
.Select(value => new { Display=value.ToString(), Value=value }) 
.ToList(); 

的改进,以接受的答案: 无需手动输入枚举成员的阵列。相反,您可以使用System.Enum.GetValues(typeof(ReadAccess))此外,而不是匿名类型列表中,您可以使用列表从字典(词典不被接受作为数据源):

ReadDataGridViewComboBoxColumn.DataSource= System.Enum.GetValues(typeof(ReadAccess)) 
    .Cast<Enum>.ToDictionary<string, Enum>((e) => e.ToString(), (e) => e).ToList; 

或直接在KeyValuePair列表

ReadDataGridViewComboBoxColumn.DataSource = System.Enum.GetValues(typeof(ReadAccess)) 
    .Cast<Enum>.Select((value) => new KeyValuePair<string, enum>(value.ToString(), (value))); 

仍然有必要(但DisplayMember现在是“密钥”):

ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess); 
ReadDataGridViewComboBoxColumn.ValueMember = "Value"; 
ReadDataGridViewComboBoxColumn.DisplayMember = "Key";