C#中数据源绑定DataSource以及相关控件(DataGridView)的使用总结
我们在编程过程中,会涉及到表格数据的显示,存储等,就可能涉及到DataGridView,DataSource, DataTable等概念。
下面我就我自己模糊的一些知识点串讲以下:
1)首先我要讲的是一些控件:
Control: 控件基类,有一个DataBindings对象,它是一个ControlBindingCollection类,这个类继承与BindingsCollection,里面有一个Binding的列表对象,其中Binding对象时一个记录了属性名,数据源,数据成员等的对象。还有个BindingContext的虚属性对象,这个是记录了DataSource和DataMember的对象的集合。
DataGridView:继承与Control,本身还有一个DataSource对象(object),还有一个DataMember(string),他们两构成了DataGridViewDataConnection对象,这个对象除了这两个对象引用外,还有DataGridView这个控件,还有一个CurrencyManager,这个CurrencyManager是继承自BindingManagerBase,根据BindingContext返回指定的CurrencyManager。然后这个BindingMangerBase里面维护了一个IList的列表。可以显示多列。
ListControl:这控件继承自Control,本身也有DataSource对象,还有一个DisplayMember和ValueMember属性,这两个属性是BindingMemberInfo对象。只能显示一列。其继承类有ListBox,ComboBox.
2)控件大致介绍了下有什么后,接下来就是绑定的源头了,我们用到了BindingSource类,这个类实现了IBindingList,IBindingList, IList, ICollection接口。BindingSource的成员中有DataSource,这个是个object对象,在赋值后内部构造一个CurrencyManager,这个对象就可以维护资源列表了。
3)那么谁可以赋值给BindingSource呢?一般实现了IList, IListSource(DataTable,DataSet),IBindingList(BindingList<T>),IBindingListView(BindingSource)的对象都可以赋值。
4)也就是说BindingSource是维护数据与控件之间的一个纽带,它维护一个数据的列表,赋值给控件,控件就可以显示相应的数据,相当于三者像一根绳上的蚂蚱。
5)我们可以看到有两个属性:DataBindings, DataSource, 他们都可以跟数据源建立联系,区别在于:DataBindings一般都是建立控件的属性与数据源的某个属性之间的关系,是属于Control的层次定义的,而DataSource不是属于Control的,有些控件可能没有,一般都是给列表控件如ListControl和DataGridView显示数据用。
6)另外DataGridView和ListControl有几个属性有点区别,DataGridView有一个DataMember成员(string),因为我们这个DataGridView有可能绑定到一个DataSet,这个有可能有很多表,或者是一个列表对象,其成员中有子成员也是列表对象,这个时候我们就需要设置DataMember。而ListControl没有DataMember成员,但是有ValueMember和DisplayMember两个成员,有什么区别呢?DisplayMember的意思就是指我要显示哪个成员,当我们绑定一个数据源给这个控件的DataSource后,这个一般都是指一个表类型的数据,然后DisplayMember指定我们要显示的列名(因为只能显示一列),然后就塞选出这一列值给显示出来,然后如果程序要获得值,那么就要设置ValueMember成员,也就是说我显示和获取的值可以是不同的,比如我显示一个班的人名字,可以获得每个名字的学号,另外SelectedValue和SelectedItem的区别在于,SelectedItem指的是选中的那一行的对象(虽然只显示了一列,但是实际数据可能不止一列),而SelectedValue指的是选中的特定行列的数据,比如我一个班级,每行是学生信息对象,然后DisplayMember表示姓名这一列,ValueMember表示学号这一列,如果我选中了”小王“,那么SelectedValue就是小王的学号,而SelectedItem就是指小王这个学生的信息对象。
下面是实际以代码为例来消化这些知识点:
1)下面先举例说明下DataGridView绑定数据的几种方式,第一种直接添加行列:
//构造列并设置列名
dataGridView1.ColumnCount = ;
dataGridView1.Columns[].Name = "Name";
dataGridView1.Columns[].Name = "Age";
dataGridView1.Columns[].Name = "ID"; //添加行
string[] row0 = { "Zhong", "", "" };
string[] row1 = { "Jing", "", "" };
dataGridView1.Rows.Add(row0);
dataGridView1.Rows.Add(row1); //可以更改显示列顺序
dataGridView1.Columns[].DisplayIndex = ;
dataGridView1.Columns[].DisplayIndex = ;
dataGridView1.Columns[].DisplayIndex = ;
第二种:使用BindingSource类:
//构造数据源
BindingSource bs = new BindingSource();
Bus bus1, bus2, bus3;
bs.Add(bus1 = new Bus("Benz", "Red"));
bs.Add(bus2 = new Bus("BME", "Green"));
bs.Add(bus3 = new Bus("Dazong", "Blue"));
bus1.People.Add(new Person("Lixiaoming"));
bus1.People.Add(new Person("Daming"));
bus2.People.Add(new Person("xiaoli"));
bus3.People.Add(new Person("linlin"));
dataGridView2.DataSource = bs;
第三种指定BindingSource的DataMember,这就解释了第二种中为什么People不能显示的原因(虽然可以通过其他的办法显示出来):
//构造数据源
BindingSource bs = new BindingSource();
Bus bus1, bus2, bus3;
bs.Add(bus1 = new Bus("Benz", "Red"));
bs.Add(bus2 = new Bus("BME", "Green"));
bs.Add(bus3 = new Bus("Dazong", "Blue"));
bus1.People.Add(new Person("Lixiaoming"));
bus1.People.Add(new Person("Daming"));
bus2.People.Add(new Person("xiaoli"));
bus3.People.Add(new Person("linlin"));
dataGridView3.DataSource = bs;
dataGridView3.DataMember = "People";
其中用到的公共汽车类和人类的定义如下:
/// <summary>
/// 公共汽车类
/// </summary>
public class Bus
{
private static int lastID = 0;
private string _busType;
private string _color;
public Bus(string busType,string color)
{
_busType = busType;
_color = color;
_id = ++lastID;
}
private int _id;
public int ID { get { return _id; } } public string Color { get { return _color; } }
public string BusType { get { return _busType; } } private List<Person> _people = new List<Person>();
public List<Person> People
{
get { return _people; }
} } public class Person
{
private static int lastID = 0;
public Person(string name)
{
_name = name;
_id = ++lastID;
}
private int _id;
public int ID
{
get { return _id; }
}
private string _name; public string Name
{
get { return _name; }
} }
这三种方式其实大同小异,还可以有很多变种,要注意的是第二种中people是没有显示出来的,因为其是列表结构,第三种中是直接把列表对象的people列表成员作为DataMember,这样显示的自然就是People中的属性了
2)ListBox的绑定:
第一种直接添加成员,这里直接给Items添加成员。
List<string> names =new List<string>() { "xiaoxiao", "dada", "xuxu" };
listBox1.Items.AddRange(names.ToArray());
第二种也可以是直接添加成员,直接看代码:
List<Bus> buses = new List<Bus>();
Bus bus1, bus2, bus3;
buses.Add(bus1 = new Bus("Benz", "Red"));
buses.Add(bus2 = new Bus("BME", "Green"));
buses.Add(bus3 = new Bus("Dazong", "Blue"));
bus1.People.Add(new Person("Lixiaoming"));
bus1.People.Add(new Person("Daming"));
bus2.People.Add(new Person("xiaoli"));
bus3.People.Add(new Person("linlin")); listBox3.DataSource = buses;
//这样也可以
// listBox3.Items.AddRange(buses.ToArray());
listBox3.DisplayMember = "Color";
这种方式时先构造列表集合,但是列表中的成员不止一个成员,所以需要设置DisplayMember,列表集合也可以赋值给DataSource,达到的效果是一样的。
第三种使用BindingSource,直接看代码:
//构造数据源
BindingSource bs = new BindingSource();
Bus bus1, bus2, bus3;
bs.Add(bus1 = new Bus("Benz", "Red"));
bs.Add(bus2 = new Bus("BME", "Green"));
bs.Add(bus3 = new Bus("Dazong", "Blue"));
bus1.People.Add(new Person("Lixiaoming"));
bus1.People.Add(new Person("Daming"));
bus2.People.Add(new Person("xiaoli"));
bus3.People.Add(new Person("linlin")); listBox2.DataSource = bs;
listBox2.DisplayMember = "Color";
这种方式相当于在集合数据对象与控件之间建立了一个纽带。可以看出这几种方式基本上是差不多的
3)DataBindings.
Control的DataBindings一般用于添加控件的属性与数据源绑定起来,以达到控件的表现形式与数据源同步。看例子:
Bus bus1, bus2, bus3;
buses.Add(bus1 = new Bus("Benz", "Red"));
buses.Add(bus2 = new Bus("BME", "Green"));
buses.Add(bus3 = new Bus("Dazong", "Blue"));
bus1.People.Add(new Person("Lixiaoming"));
bus1.People.Add(new Person("Daming"));
bus2.People.Add(new Person("xiaoli"));
bus3.People.Add(new Person("linlin")); listBox4.DataSource = buses;
listBox4.DisplayMember = "Color";
//控件的属性绑定到一个列表,这里如果改变textbox1的Text,buses好像不作更改?
textBox1.DataBindings.Add("Text", buses, "BusType"); mybool.Name = "hello";
//控件的属性绑定到一个对象属性,如果在外面直接修改Text,mybool也会同步修改,如果是通过程序修改,
//就要执行WriteValue();
textBox2.DataBindings.Add("Text", mybool, "Name");
class SingleClass
{
private String _name; public String Name
{
get { return _name; }
set { _name = value; }
} }
private void button8_Click(object sender, EventArgs e)
{
textBox2.Text = "BME1";
textBox2.DataBindings["Text"].WriteValue();
}
我这里首先把一个集合对象buses的BusType绑定到一个TextBox的Text属性, 这个Text的属性就会随着选中的buses的集合元素改变而改变,但是这里有一点,如果我们修改TextBox的Text属性,buses是得不到修改的。
而如果我们把一个对象属性(mybool.Name)绑定到TextBox的Text属性上,如果我们在控件中直接修改Text属性,那么mybool这个对象也相应的变化了,如果通过代码修改的话就要调用WriteValue()方法。
4)关于数据的同步,如果修改了其中的一个环节,其他所有环节都会有更新,见如下代码:
//构造数据源
BindingSource bs = new BindingSource();
Bus bus1, bus2, bus3;
bs.Add(bus1 = new Bus("Benz", "Red"));
bs.Add(bus2 = new Bus("BME", "Green"));
bs.Add(bus3 = new Bus("Dazong", "Blue"));
bus1.People.Add(new Person("Lixiaoming"));
bus1.People.Add(new Person("Daming"));
bus2.People.Add(new Person("xiaoli"));
bus3.People.Add(new Person("linlin"));
dataGridView2.DataSource = bs;
//因为Color属性不是只读,所以可以再控件中修改这个值,修改后,数据源就会 更新textbox3.Text
this.textBox3.DataBindings.Add("Text", bs, "Color");
当我们修改DataGridView的Color单元格后(绑定的对象属性不是只读才能修改),BindingSource也会更新,所以TextBox.Text也得到了更新。
http://files.cnblogs.com/files/monkeyZhong/DataGridViewExample.zip
C#中数据源绑定DataSource以及相关控件(DataGridView)的使用总结的更多相关文章
- 【案例分享】在 React 框架中使用 SpreadJS 纯前端表格控件
[案例分享]在 React 框架中使用 SpreadJS 纯前端表格控件 本期葡萄城公开课,将由国电联合动力技术有限公司,资深前端开发工程师——李林慧女士,与大家在线分享“在 React 框架中使用 ...
- Android开发工程师文集-相关控件的讲解,五大布局
前言 大家好,给大家带来Android开发工程师文集-相关控件的讲解,五大布局的概述,希望你们喜欢 TextView控件 TextView控件有哪些属性: android:id->控件的id a ...
- [WinForm] 使用反射将业务对象绑定到窗体或控件容器
在WebForm中,可以使用反射将业务对象绑定到 ASP.NET 窗体控件.最近做Winform项目,也参考WebForm中的代码实现同样的功能. Winform没有提供类似WebForm中的 ...
- C#中禁止跨线程直接访问控件
C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...
- XCODE中使用Main.Storyboard拉入控件并实现事件(Swift语言)
如何在XCODE中的Main.Storyboard内拉入控件并实现一个简单的效果呢?本人由于刚接触Swift语言不久,对于IDE的操作还是很生疏,不懂了就在网上参考了网上前辈们的文章.以下我将演示如何 ...
- [转载]在网页中插入media,RealPlayer等控件
[转载]在网页中插入media,RealPlayer等控件 (2012-11-02 20:27:43) 转载▼ 标签: 转载 原文地址:在网页中插入media,RealPlayer等控件作者:Mo ...
- jQuery学习笔记(在js中增加、删除及定位控件的操作)
代码内容很多都是从amazeui直接copy过来的,先声明,请不要说在下抄袭- - <!-------------------- HTML代码 ----------------------> ...
- InteropBitmap指定内存,绑定WPF的Imag控件时刷新问题。
1.InteropBitmap指定内存,绑定WPF的Imag控件的Source属性 创建InteropBitmap的时候,像素的格式必须为PixelFormats.Bgr32, 如果不是的话在绑定到I ...
- iOS中如何让TextView和TextField控件支持return键收起输入法
TextView和TextField控件是iOS中负责接收用户输入的控件,那当用户输入完成时怎么收起面板呢? 1.TextView和TextField控件获得焦点之后的第一反应就是弹出输入法面板: 2 ...
随机推荐
- Xcode export/upload error: Your session has expired. Please log in-b
1.Xcode export/upload error: Your session has expired. Please log in 我在stack over flow上找到的答案: 一看pre ...
- 在Xcode中如何屏蔽某个源文件的编译警告信息
某些时候如果我们的源码在编译过程中出现大量的编译警告时,看起来是挺不爽的:但又确实没办法解决警告问题的时候,我们可以使用下面的方法来屏蔽指定的某个文件的所有警告信息. 1.在Xcode中选中工程文件. ...
- 转:cookie和session(二)——php应用
文章来自于:http://blog.csdn.net/half1/article/details/21650211 本文将介绍cookie在session在php中的基本用法. 1.cookie ...
- SCALA当的trait
不是特别懂,但感觉和RUBY当中的MIX-IN功能有几分相似,这又扯到了多重继承及JAVA当中的接口虚拟类了.. package com.hengheng.scala class UseTrait { ...
- SCALA表达示简例
作了解,感觉比一般的差距有点大哟. package com.hengheng.scala class HelloScala { } object HelloScala { def main(args: ...
- keil优化等级设置
附表:Keil C51中的优化级别及优化作用 级别说明 0 常数合并:编译器预先计算结果,尽可能用常数代替表达式.包括运行地址计算. 优化简单访问:编译器优化访问8051系统的内部数据和位地址. 跳转 ...
- LTE发射机ACLR性能的测量技术
现代无线服务提供商正致力于不断扩大带宽,为更多用户提供互联网协议(IP)服务.长期演进技术(LTE)是对当前部署的3GPP 网络进行增强并创造更多更重要应用的新一代蜂窝技术.LTE 的体系结构复杂同时 ...
- pl/sql 在一个程序块里打印日志输出到表格
declare v_number NUMBER; v_number2 NUMBER; begin execute immediate 'truncate table t2'; insert into ...
- HDFS基础和java api操作
1. 概括 适合一次写入多次查询情况,不支持并发写情况 通过hadoop shell 上传的文件存放在DataNode的block中,通过linux shell只能看见block,看不见文件(HDFS ...
- SherlockactionBar中手动调用onCreateOptionsMenu的办法
我们有时候要做做事的时候,要提前拿到 ActionBar中的menuItem,但是,会出现为空的情况.怎么办呢? 比如这里: @Override public boolean onCreateOpti ...