一  需求介绍

一般像枚举类型的数据,我们在数据库里存储着诸如(1、2、3、4…)或者(“001”、“002”、“003”…)此类,但是界面上我们想要显示的是具体的文本内容,以便用户理解使用。所以在从数据库中加载出来的数据 DataTable 绑定到 DataGridView 上时,就需要其中一些枚举列采用下拉框,并绑定对应的枚举数据源。

二  具体实现

首先,如果 DataGridView 的 AutoGenerateColumns 为 true 时,在绑定 DataTable 到 DataGridView 上时,会自动生成绑定数据中的各列,且默认均为普通的 DataGridViewTextBoxColumn 。所以如果要设置 DataGridView 中的下拉列,首先要把 AutoGenerateColumns 设置为 false

 /// <summary>
/// Sample
/// DataGridView绑定DataTable,ComboBox列绑定enum枚举
/// </summary>
public MainForm()
{
InitializeComponent(); DataTable dataTable = CreateDataTable();
dataGridView.AutoGenerateColumns = true;// 默认设置
dataGridView.DataSource = dataTable;
// SetGridView(dataTable);
} /// <summary>
/// 构建数据源
/// 可以从数据库读取出来构建DataTable数据源
/// </summary>
/// <returns>DataTable数据表</returns>
public DataTable CreateDataTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(int)));
dt.Columns.Add(new DataColumn("Name", typeof(string)));
dt.Columns.Add(new DataColumn("EnumCol1", typeof(int)));
dt.Columns.Add(new DataColumn("EnumCol2", typeof(string)));
Random r = new Random();
for (int i = 0; i < 50; i++)
{
DataRow dr = dt.NewRow();
dr[0] = r.Next();
dr[1] = "Name = " + r.Next();
dr[2] = r.Next(1, 5);
dr[3] = "EnumCol_" + r.Next(1, 5);
dt.Rows.Add(dr);
} return dt;
}

效果图(AutoGenerateColumns = true):

在将 AutoGenerateColumns 属性设置为 false 后,就要手动生成各列了。其中 EnumCol1 列要绑定一个枚举类型,EnumCol2 要绑定一个字典类型(Dictionary<string, string>)。

 /// <summary>
/// 枚举1
/// </summary>
private enum EnumCol1
{
A = 1,
B = 2,
C = 3,
D = 4,
E = 5
}
/// <summary>
/// 枚举转字典
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumType"></param>
/// <returns></returns>
private Dictionary<int, string> EnumToDictionary(Type enumType)
{
Dictionary<int, string> result = new Dictionary<int, string>();
foreach (int key in Enum.GetValues(enumType))
{
string value = Enum.GetName(enumType, key);
result.Add(key, value);
} return result;
}

通过上面的代码中 EnumToDictionary 方法把枚举类型转换为字典类型,这样就可以统一处理数据绑定了。

 /// <summary>
/// 设置DataGridView视图
/// </summary>
/// <param name="dt">数据源表</param>
public void SetGridView(DataTable dt)
{
// 在放弃绑定时自动生成列,并且还未初始化DataGridView的列时
// 手动生成各列
if (!dataGridView.AutoGenerateColumns && dataGridView.Columns.Count == 0)
{
Dictionary<int, string> dic = EnumToDictionary(typeof(EnumCol1));
foreach (DataColumn dc in dt.Columns)
{
string colName = dc.ColumnName;
DataGridViewColumn dgvc = null;
if (colName.StartsWith("EnumCol"))// 生成下拉列
{
dgvc = new DataGridViewComboBoxColumn();
BindingSource bs = new BindingSource();
if (colName.EndsWith(""))// 绑定枚举1
{
bs.DataSource = dic;
dgvc.ValueType = typeof(int);
}
else if (colName.EndsWith(""))// 绑定枚举2
{
bs.DataSource = new Dictionary<string, string>()
{
{"EnumCol_1", "AA"},
{"EnumCol_2", "BB"},
{"EnumCol_3", "CC"},
{"EnumCol_4", "DD"},
{"EnumCol_5", "EE"}
};
dgvc.ValueType = typeof(string);
}
((DataGridViewComboBoxColumn)dgvc).DisplayMember = "Value";
((DataGridViewComboBoxColumn)dgvc).ValueMember = "Key";
((DataGridViewComboBoxColumn)dgvc).DataSource = bs;
((DataGridViewComboBoxColumn)dgvc).DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
((DataGridViewComboBoxColumn)dgvc).FlatStyle = FlatStyle.Flat;
}
else// 生成普通列
{
dgvc = new DataGridViewTextBoxColumn();
}
dgvc.Name = colName;
dgvc.DataPropertyName = colName;// 保证该列的值绑定到DataTable中colName列上
dataGridView.Columns.Add(dgvc);
}
}
}

在列类型为 DataGridViewComboBoxColumn,且要绑定字典数据源(Dictionary)时,需要通过 BindingSource 。即:

BindingSource bs = new BindingSource();
bs.DataSource = dic;
((DataGridViewComboBoxColumn)dgvc).DataSource = bs;

需要特别注意的是==>

48行代码:

dgvc.DataPropertyName = colName;  表示该下拉列的值绑定对应于数据源 DataTable 中 colName 列数据;

37行、38行代码:

((DataGridViewComboBoxColumn)dgvc).DisplayMember = "Value";

((DataGridViewComboBoxColumn)dgvc).ValueMember = "Key";

DisplayMember 是表示下拉框显示的值绑定于 dgvc 的数据源的某个位置(字典的Value);

ValueMember 是表示下拉框实际值绑定于 dgvc 的数据源的某个位置(字典的Key);

23行、35行代码:

dgvc.ValueType = typeof(int);

dgvc.ValueType = typeof(string);

这两句则是指定该列绑定数据源里该列的类型。此时,必须保证数据源 DataTable 里该列的值类型,必须和该列的 ValueMember 属性绑定的数据源类型一致。以文中例子,即 datagridview 的列 EnumCol1 和列 EnumCol2 的数据类型必须和所绑定的 Dictionary 的 Key 类型一致(因为 dgvc 的 ValueMember 属性绑定于 Key)。

效果图:

三  追加几句

1、SQLite 数据库中的 INTEGER 和 INT 类型区别需要通过“Tools –> Options –> Type Mappings”来确定。

但是实际上,其中 INT 类型是与C#的 Int32 对应,如果将 INTEGER 类型的列绑定到 Dictionary<int, string>上,是会报如下错误的:

2、本文以 DataGridViewComboBoxColumn 列绑定 Dictionary 字典数据源为例说明具体绑定细节,当然该类型列也可以绑定于 DataTable 等其他类型数据,只要设置好绑定细节就可以了。

[WinForm] DataGridView 绑定 DT && ComboBox 列绑定 Dict的更多相关文章

  1. WPF使用附加属性绑定,解决data grid列绑定不上的问题

    背景 需要对datagrid的列header添加自定义属性,然后绑定,并根据不同的列header绑定不同的值,传统的加扩展类太麻烦,而附加属性的特点更适用于这种场景. 1.xaml 代码 <Da ...

  2. Winform开发中如何将数据库字段绑定到ComboBox控件

    最近开始自己动手写一个财务分析软件,由于自己也是刚学.Net不久,所以自己写的的时候遇到了很多问题,希望通过博客把一些印象深刻的问题记录下来. Winform开发中如何将数据库字段绑定到ComboBo ...

  3. Winform开发常用控件之DataGridView的简单数据绑定——代码绑定DataSet、DataTable、IList、SqlDataReader

    前文介绍了Winform为DataGridView提供的数据自动绑定功能,下面介绍一下采用代码的数据绑定 1.用DataSet和DataTable为DataGridView提供数据源 先上代码 pri ...

  4. C# 控制datagridview的combox属性的列绑定数据

    //datagridvie列绑定list的数据 List<User> listChange = GetChange();//查询数据库内容,保存到list this.datagridvie ...

  5. Datagridview 列绑定

    Datagridview 列绑定 dataGridView1.Columns.Clear(); dataGridView1.Columns.Add("id", "id&q ...

  6. 【Winform】DataTable绑定到ComboBox

    我们从数据库中查询出来的数据存放在Datatable中 1.DataTable绑定到ComboBox上 cmbRole.DataSource = datatable; cmbRole.DisplayM ...

  7. WinForm DataGridView 绑定泛型List(List<T>)/ArrayList不显示的原因和解决

    背景:无意间遇到了一个不大不小的问题,希望对一些遇到的人有所帮助! 一.问题 WinForm DataGridView 绑定泛型List (List<T>)/ArrayList不显示,UI ...

  8. C# datagridview列绑定类中类的属性

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://www.cnblogs.com/linghaoxinpian/p/5906374. ...

  9. winform datagridview 绑定泛型集合变得不支持排序的解决方案

    原文:winform datagridview 绑定泛型集合变得不支持排序的解决方案 案例: 环境:Winform程序 控件:Datagridview 现象:Datagridview控件绑定到List ...

随机推荐

  1. [C#] 简单的 Helper 封装 -- SQLiteHelper

    using System; using System.Data; using System.Data.SQLite; namespace SqliteConsoleApp { /// <summ ...

  2. 尝试asp.net mvc 基于controller action 方式权限控制方案可行性

    微软在推出mvc框架不久,短短几年里,版本更新之快,真是大快人心,微软在这种优秀的框架上做了大量的精力投入,是值得赞同的,毕竟程序员驾驭在这种框架上,能够强力的精化代码,代码层次也更加优雅,扩展较为方 ...

  3. Java进击C#——前言

    本章简言 记得三年前笔者来到现在的公司的时候,公司人口不出十个人.那个时候笔者刚从日本回来,想在福州.厦门.青岛找一个合适自己发展的机会.最后我的一个福州的朋友打电话希望我能过去帮他,跟他一起创业.这 ...

  4. C#——传值参数(1)

    //我的C#是跟着猛哥(刘铁猛)(算是我的正式老师)<C#语言入门详解>学习的,微信上猛哥也给我讲解了一些不懂得地方,对于我来说简直是一笔巨额财富,难得良师! 这次与大家一起学习C#中的值 ...

  5. Android 添加ActionBar Buttons

    一.在res/menu文件夹下创建Xml文件 跟标签为menu,设置item <?xml version="1.0" encoding="utf-8"?& ...

  6. emmet,jade,haml, slim,less,sass,coffeescript等的实战优缺点

    摘要: 文章背景,来自于群内周五晚上的一次头脑风暴式的思维碰撞交流活动. 随着前端技术的蓬勃发展, 各种新技术随着生产力的需要不断的涌入我们的视野, 那今天探讨的话题是这些新时代的前端兵器谱: 一. ...

  7. 完成C++不能做到的事 - Visitor模式

    拿着刚磨好的热咖啡,我坐在了显示器前.“美好的一天又开始了”,我想. 昨晚做完了一个非常困难的任务并送给美国同事Review,因此今天只需要根据他们提出的意见适当修改代码并提交,一周的任务就完成了.剩 ...

  8. .NET里简易实现IoC

    .NET里简易实现IoC 前言 在前面的篇幅中对依赖倒置原则和IoC框架的使用只是做了个简单的介绍,并没有很详细的去演示,可能有的朋友还是区分不了依赖倒置.依赖注入.控制反转这几个名词,或许知道的也只 ...

  9. 相关query挖掘

    1.何为相关query 我通常也把相关query称为相似query,搜索日志中一个用户在短时间内的一系列搜索词被称为相关query.相关就是两个query间有一定的关系,反映了用户在当时的需求.本文就 ...

  10. eclipse下查看maven下载的源码中文乱码问题

    在项目中设置通过maven下载源代码和javadoc,直接通过eclipse浏览源代码时,发现中文为乱码.解决方法如下: 修改Eclipse中文本文件的默认编码:windows->Prefere ...