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

发布于 2024-10-01 05:55:50 字数 988 浏览 2 评论 0原文

为了在此 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 的数据源:

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

What else I have to do in order to show ReadAccess enum members in this DatagridViewComboBox?

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

here is designer-generated codes about 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;

and finally, in after InitializeComponent();, i'm setting DataGridView's DataSource:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

御守 2024-10-08 05:55:50

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

This is a problem i've come across many times. The DataGridViewComboBoxColumn doesn't know how to reconcile the difference between the enum's string representation and its integral value. Even though you set ValueType to the type of the enum, the DataGridView will try to set the cell's value to the underlying int value - this is why a FormatException will be raised during databinding.

The only way i've found to overcome this problem (short of subclassing the cell type) is to bind the DataGridViewComboBoxColumn to a data source which separates the string values from the integer values. You can use an anonymous type for this purpose:

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();

This way, the DataGridView knows how to relate the cell value with its formatted value.

沫尐诺 2024-10-08 05:55:50

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

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

Adding to the answer Bradly Smith provided: One can get all Enum values (instead of naming each individually) easily using this code:

    ReadDataGridViewComboBoxColumn.DataSource =
        new List<ReadAccess>((ReadAccess[]) Enum.GetValues(typeof(ReadAccess)))
        .Select(value => new { Display=value.ToString(), Value=(int)value })
        .ToList();
罪歌 2024-10-08 05:55:50

您不应将枚举值转换为 int。如果您遇到“无效值”之类的错误,请使用此代码:

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

You should not convert enum value to the int. Use this code if you have an error like "invalid value":

ReadDataGridViewComboBoxColumn.DataSource = new ReadAccess[]
{ ReadAccess.None, ReadAccess.Allowed }
.Select(value => new { Display=value.ToString(), Value=value })
.ToList();
枯叶蝶 2024-10-08 05:55:50

对已接受答案的改进:
无需手动将枚举成员键入为数组。相反,您可以使用 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 现在是“Key”):

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

An Improvement to accepted answer:
There is no need to type enum members as array manually. Instead you can use System.Enum.GetValues(typeof(ReadAccess)). Also, instead of anonymous type list, you can use a List from Dictionary (Dictionary isn't accepted as datasource):

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

or directly a KeyValuePair list :

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

Still necessary (but DisplayMember now is "Key") :

 ReadDataGridViewComboBoxColumn.ValueType = typeof(ReadAccess);
 ReadDataGridViewComboBoxColumn.ValueMember = "Value";
 ReadDataGridViewComboBoxColumn.DisplayMember = "Key";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文