Winform-绑定自定义类型对象下拉列表到DataGridViewComboBoxColumn
微软文档里自带的绑定对象到DataGridView示例,仅仅示例了枚举类型填充下拉列表。
关键代码:
DataGridViewComboBoxColumn CreateComboBoxWithEnums()
{
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
combo.DataSource = Enum.GetValues(typeof(Title));
combo.DataPropertyName = "Title";
combo.Name = "Title";
return combo;
}
关键就是设置列对象的DataSource和DataPropertyName属性。
但是对于自定义类型,没有设置ToString()重载方法,因此必须通过设置DisplayMember属性来指定列的显示属性。
例如存在一个Title类
class Title
{
public string Name{get;set;}
}
有一个类使用了Title类作为它的一个属性:
private class Knight
{
private string hisName;
private bool good;
private Title hisTitle;
public Knight(Title title, string name, bool good)
{
hisTitle = title;
hisName = name;
this.good = good;
}
public Knight()
{
hisTitle = Title.Sir;
hisName = "<enter name>";
good = true;
}
public string Name
{
get
{
return hisName;
}
set
{
hisName = value;
}
}
public bool GoodGuy
{
get
{
return good;
}
set
{
good = value;
}
}
public Title Title
{
get
{
return hisTitle;
}
set
{
hisTitle = value;
}
}
}
当我们需要自定义一个Title列表作为可选的下拉列表时,对于此Knight.Title的属性对应的编辑列,按照如下的方式设置会提示Cell类型不正确。
private List<Title> titles = new List<Title>(){new Title(){Name = "Sir"},new Title(){Name = "King"}};
DataGridViewComboBoxColumn CreateComboBoxWithEnums()
{
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
combo.DataSource = this.titles;
combo.DisplayMember = "Name";
combo.DataPropertyName = "Title";
combo.Name = "Title";
return combo;
}
private void EnumsAndComboBox_Load(object sender, System.EventArgs e)
{
// Populate the data source.
bindingSource1.Add(new Knight(new Title(){Name = "King"}, "Uther", true));
bindingSource1.Add(new Knight(new Title(){Name = "King"}, "Arthur", true));
bindingSource1.Add(new Knight(new Title(){Name = "Sir"}, "Mordred", false));
bindingSource1.Add(new Knight(new Title(){Name = "Sir"}, "Gawain", true));
bindingSource1.Add(new Knight(new Title(){Name = "Sir"}, "Galahad", true));
// Initialize the DataGridView.
dataGridView1.AutoGenerateColumns = false;
dataGridView1.AutoSize = true;
dataGridView1.DataSource = bindingSource1;
dataGridView1.Columns.Add(CreateComboBoxWithEnums());
// Initialize and add a text box column.
DataGridViewColumn column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "Name";
column.Name = "Knight";
dataGridView1.Columns.Add(column);
// Initialize and add a check box column.
column = new DataGridViewCheckBoxColumn();
column.DataPropertyName = "GoodGuy";
column.Name = "Good";
dataGridView1.Columns.Add(column);
// Initialize the form.
this.Controls.Add(dataGridView1);
this.AutoSize = true;
this.Text = "DataGridView object binding demo";
}
因为设置了DisplayMember,必须设置ValueMember来指定下拉选择后设置此单元格对应的值属性。如果遇到需要将下拉列表选择的自定义类型对象(Title)设置为列表绑定对象(Knight)的属性值,无论ValueMember设置为null还是"",都无法返回自定义类型对象自身。
解决办法搜索了很多,比较简单的办法是通过在Title中添加一个指向自身的属性,例如:
public Title Self{get=>this;}
然后设置combo.ValueMember="Self"获取Title对象本身,缺点要修改Title的类结构。
进阶方法是构建一个匿名类,一个属性保存显示属性,一个属性保存Title对象:
combo.DataSource = this.titles.Select(t=>new(){Name = t.Name,Self=t}).ToList();
combo.DisplayMember = "Name";
combo.ValueMember = "Self";
缺点是匿名方法比较高版本的C#才有,取代方式是使用Tuple<string, Title>()元祖类
combo.DataSource = this.titles.Select(t=>new Tuple<string, Title>(t.Name,t)).ToList();
combo.DisplayMember = "Item1";
combo.ValueMember = "Item2";
分类:
Winform
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?