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。然后这个BindingMangerBa
se⾥⾯维护了⼀个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 = 3;
dataGridView1.Columns[0].Name = "Name";
dataGridView1.Columns[1].Name = "Age";
dataGridView1.Columns[2].Name = "ID";
//添加⾏
string[] row0 = { "Zhong", "18", "001" };
string[] row1 = { "Jing", "22", "002" };
dataGridView1.Rows.Add(row0);
dataGridView1.Rows.Add(row1);
/
/可以更改显⽰列顺序
dataGridView1.Columns[0].DisplayIndex = 1;
dataGridView1.Columns[1].DisplayIndex = 0;
dataGridView1.Columns[2].DisplayIndex = 2;
第⼆种:使⽤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⼀般⽤于添加控件的属性与数据源绑定起来,以达到控件的表现形式与数据源同步。看例⼦:
1 Bus bus1, bus2, bus3;
2 buses.Add(bus1 = new Bus("Benz", "Red"));
3 buses.Add(bus2 = new Bus("BME", "Green"));
4 buses.Add(bus3 = new Bus("Dazong", "Blue"));
5 bus1.People.Add(new Person("Lixiaoming"));
6 bus1.People.Add(new Person("Daming"));
7 bus2.People.Add(new Person("xiaoli"));
8 bus3.People.Add(new Person("linlin"));
9
10 listBox4.DataSource = buses;
11 listBox4.DisplayMember = "Color";
12//控件的属性绑定到⼀个列表,这⾥如果改变textbox1的Text,buses好像不作更改?
13 textBox1.DataBindings.Add("Text", buses, "BusType");
14
15 mybool.Name = "hello";
16//控件的属性绑定到⼀个对象属性,如果在外⾯直接修改Text,mybool也会同步修改,如果是通过程序修改,
17//就要执⾏WriteValue();
18 textBox2.DataBindings.Add("Text", mybool, "Name");
View Code
1class SingleClass
2 {
3private String _name;
4
5public String Name
6 {
7get { return _name; }
8set { _name = value; }
9 }
10
11 }
12private void button8_Click(object sender, EventArgs e)
13 {
14 textBox2.Text = "BME1";
15 textBox2.DataBindings["Text"].WriteValue();
16 }
View Code
我这⾥⾸先把⼀个集合对象buses的BusType绑定到⼀个TextBox的Text属性, 这个Text的属性就会随着选中的buses的集合元素改变⽽改变,但是这⾥有⼀点,如果我们修改TextBox的Text属性,buses是得不到修改的。
⽽如果我们把⼀个对象属性(mybool.Name)绑定到TextBox的Text属性上,如果我们在控件中直接修改Text属性,那么mybool这个对象也相应的变化了,如果通过代码修改的话就要调⽤WriteValue()⽅法。
4)关于数据的同步,如果修改了其中的⼀个环节,其他所有环节都会有更新,见如下代码:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论