一  需求介绍

一般像枚举类型的数据,我们在数据库里存储着诸如(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. Android 5.0 到 Android 6.0 + 的深坑之一 之 .so 动态库的适配

    (原创:http://www.cnblogs.com/linguanh) 目录: 前序 一,问题描述 二,为何会如此"无情"? 三,目前存在该问题的知名SDK 四,解决方案,1 对 ...

  2. 使用 Android Studio 检测内存泄漏与解决内存泄漏问题

    本文在腾讯技术推文上 修改 发布. http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BF ...

  3. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  4. 根据ip判断返回城市名称查询当地天气

    <?phpheader("content-type:text/html;charset=utf-8");date_default_timezone_set("Asi ...

  5. 【干货分享】流程DEMO-出差申请单

    流程名: 出差申请  业务描述: 员工出差前发起流程申请,流程发起时,会检查预算,如果预算不够,将不允许发起费用申请,如果预算够用,将发起流程,同时占用相应金额的预算,但撤销流程会释放相应金额的预算. ...

  6. EQueue 2.3.2版本发布(支持高可用)

    前言 前段时间针对EQueue的完善终于告一段落了,实在值得庆祝,自己的付出和坚持总算有了成果.这次新版本主要为EQueue实现了集群功能,基本实现了Broker的高可用.另外还增加了很多实用的功能, ...

  7. Linux环境下shell和vim中乱码原因及消除办法

    shell和vim中乱码原因及消除办法 作者:Jack47 在Linux下开发,经常遇到乱码问题:shell或者vim中显示不了中文,或者能够显示,但不能输入中文.每次都是上网去搜,或者同事告诉我一些 ...

  8. 【Java并发编程实战】----- AQS(一):简介

    在前面博客中,LZ讲到了ReentrantLock.ReentrantReadWriteLock.Semaphore.CountDownLatch,他们都有各自获取锁的方法,同时相对于Java的内置锁 ...

  9. 2000条你应知的WPF小姿势 基础篇<74-77 WPF 多窗口Tips>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000ThingsYou Should Know About C# 和 2,00 ...

  10. 读取xml数据装配到字典中

    public Dictionary<string, string> GetXml() { Dictionary<string, string> dic = new Dictio ...