一  需求介绍

一般像枚举类型的数据,我们在数据库里存储着诸如(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. jQuery学习之路(4)- 动画

    ▓▓▓▓▓▓ 大致介绍 通过jQuery中基本的动画方法,能够轻松地为网页添加非常精彩的视觉效果,给用户一种全新的体验 ▓▓▓▓▓▓ jQuery中的动画 ▓▓▓▓▓▓ show()和hide()方法 ...

  2. c#比较两个数组的差异

    将DataTable中某一列数据直接转换成数组进行比较,使用的Linq,要引用命名空间using System.Linq; string[] arrRate = dtRate.AsEnumerable ...

  3. BPM配置故事之案例6-条件可见与条件必填

    小明兴奋的告诉大毛自己独立解决了必填和水印问题,腹黑的大毛决定给小明出一个进阶问题刷一下存在感. 大毛:我再考考你,我把表单改成了这样(下图).怎么做到,预算状态为"预算内"时,不 ...

  4. Java集合类--温习笔记

    最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...

  5. Ubuntu设置root用户登录图形界面

    Ubuntu默认的是root用户不能登录图形界面的,只能以其他用户登录图形界面.这样就很麻烦,因为权限的问题,不能随意复制删除文件,用gedit编辑文件时经常不能保存,只能用vim去编辑. 解决的办法 ...

  6. [转]nopCommerce Widgets and How to Create One

    本文转自:https://dzone.com/articles/what-are-nopcommerce-widgets-and-how-to-create-one A widget is a sta ...

  7. 搭建TFS 2015 Build Agent环境(一)

    Download the build agent Downloading the build agent is really simple. Navigate to your TFS control ...

  8. mono for android中使用dapper或petapoco对sqlite进行数据操作

    在mono for android中使用dapper或petapoco,很简单,新建android 类库项目,直接把原来的文件复制过来,对Connection连接报错部分进行注释和修改就可以运行了.( ...

  9. 2016年我们重新思考移动互联网创业的风险, 微信还是APP?

    感觉这两年前端开发又火起来了,很多做内容创业和做微电商创业的人,往往都选择了运营微信号.对于做纯技术开发的人来说,一般是看不上微信号的,感觉没什么技术含量,或者说没什么技术壁垒.也有另一批人观点相反的 ...

  10. App开发的新趋势

    移动开发这些年,移动开发者人数越来越多,类似的培训公司发展也很快,不过伴随着的是移动应用的需求这几年发展更为旺盛.要开发好的App,纯原生开发肯定是最佳选择.但是这么多年发展,原生开发的难度并没有降低 ...