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

为了在DatagridViewComboBox中显示ReadAccess枚举成员,我还需要做些什么?

 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 

这是我遇到过很多次的问题。 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知道如何将单元格值与其格式化值相关联。

添加到答案Bradly Smith提供:使用此代码可以轻松获取所有Enum值(而不是单独命名每个):

  ReadDataGridViewComboBoxColumn.DataSource = new List((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.ToDictionary((e) => e.ToString(), (e) => e).ToList; 

或直接KeyValuePair列表

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

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

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