如何在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";