一  需求介绍

一般像枚举类型的数据,我们在数据库里存储着诸如(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. Mysql存储引擎及选择方法

    0x00 Mysql数据库常用存储引擎 Mysql数据库是一款开源的数据库,支持多种存储引擎的选择,比如目前最常用的存储引擎有:MyISAM,InnoDB,Memory等. MyISAM存储引擎 My ...

  2. JavaScript中事件处理

    先看看下面一道题目,请评价以下代码并给出改进意见: if (window.addEventListener) {//标准浏览器 var addListener = function(el, type, ...

  3. 「译」JUnit 5 系列:环境搭建

    原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...

  4. Mysql - 触发器/视图

    触发器在之前的项目中, 应用的着实不多, 没有办法的时候, 才会去用这个. 因为这个东西在后期并不怎么好维护, 也容易造成紊乱. 我最近的项目中, 由于数据库设计(别人设计的)原因, 导致一些最简单功 ...

  5. Greenplum 的分布式框架结构

    Greenplum 的分布式框架结构 1.基本架构 Greenplum(以下简称 GPDB)是一款典型的 Shared-Nothing 分布式数据库系统.GPDB 拥有一个中控节点( Master ) ...

  6. Forward+ Rendering Framework

    近几天啃各种新技术时又一个蛋疼的副产品...额,算是把AMD的Forward+ Sample抄了一遍吧. 其实个人感觉这个AMD大肆宣传的Forward+跟Intel很早之前提的Tiled-Based ...

  7. 我的MYSQL学习心得(十四) 备份和恢复

    我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  8. ES6+ 现在就用系列(二):let 命令

    系列目录 ES6+ 现在就用系列(一):为什么使用ES6+ ES6+ 现在就用系列(二):let 命令 ES6+ 现在就用系列(三):const 命令 ES6+ 现在就用系列(四):箭头函数 => ...

  9. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  10. ASP.NET MVC Model元数据(四)

    ASP.NET MVC Model元数据(四) 前言 前面的篇幅讲解了Model元数据生成的过程,并没有对Model元数据生成过程的内部和Model元数据结构的详细解释.看完本篇后将会对Model元数 ...