关闭

[c#] BindingSource

标签: c#bindingdatasettextboxautocompletenull
10166人阅读 评论(2) 收藏 举报
分类:

 

1.引言

BindingSource组件是数据源和控件间的一座桥,同时提供了大量的API和Event供我们使用。使用这些API我们可以将Code与各种具体类型数据源进行解耦;使用这些Event我们可以洞察数据的变化。

2.简单绑定

DataTable myTable = myTableAdapter.GetData();//创建Table

BindingSource myBindingSource= new BindingSource();//创建BindingSource

DataGridView myGrid = new DataGridView();//创建GridView

myGrid.DataSource = myBindingSource;//将BindingSource绑定到GridView

myTable;//绑定数据到BindingSource

注:

1)绑定到DataTable,其实是绑定到DataTable提供的DataView上。每个DataTable都有一个缺省的DataView

2)DataView是绑定的实质,正如其名,它是DataTable的数据的展现。因此可以对同一个DataTable

,构建多个DataView,进而可以对这同样的数据实施不同的过滤、排序等方法,从不同侧面展示DataTable。这也体现了一定的MVC思想。

3)BindingSouce也可作为数据(其实是数据引用)的容器在不同窗体间传递,从而实现在弹出窗体中对数据的编辑

3.主细表

image

以上图所示数据为例:

1)DataSet:myDataSet

2)DataTable:ParentTable、ChildTable、GrandChildTable

3)Relation:FK_Parent_Child、FK_Child_GrandChild

//绑定父数据

parentBindingSource.DataSource = myDataSet;

parentBindingSource.DataMember = "ParentTable";

m_GrandParentGrid.DataSource = m_GrandParentBindingSource;

//绑定子数据。
childBindingSource.DataSource = parentBindingSource;//绑定到“父BindingSource”,而不是父Table

childBindingSource.DataMember = "FK_Child_GrandChild";//绑定到“父-子Relation”

//绑定孙子数据。
grandChildBindingSource.DataSource = childBindingSource;//绑定到“子BindingSource”

grandChildBindingSource.DataMember = "FK_Child_GrandChild";//绑定到“子-孙Relation”

这样你就可以在Form上摆上3个DataView,分布绑定到这3个BindingSouce,很容易就实现了主细表关联展现。

4.数据操纵

要操纵数据,首先需要获取当前数据项。BindingSource的Current属性返回DataRowView类型的对象(就像DataView是对DataTable的封装一样,DataRowView是对DataRow的封装),它是对当前数据项的封装,可以通过类型转换变成你想要的对象。

DataRowView currentRowView = myBindingSource.Current;//获取当前RowView

CustomersRow custRow = currentRowView.Row as CustomersRow;//类型转换为当前数据项

string company = custRow.CompanyName;//使用当前数据项

string phoneNo = custRow.Phone;

5.用BindingSource做数据容器

BindingSource还可以用作数据容器,即便它没有绑定到数据源上,它内部有一个可以容纳数据的list。

5.1Add方法

调用Add方法会在BindingSource的list中插入数据项。如果这时第一次插入数据,并且没有绑定数据,那么插入数据的类型就决定了今后此list中数据的类型。

注:

1)此时再插入其它类型对象会抛出InvalidOperationException异常

2)设置DataSource属性时会刷新list,造成Add方法添加到list中的数据丢失

5.2AddNew方法

AddNew方法返回BindingSourc所容纳数据类型的对象;如果之前没有容纳数据,则会返回Object对象。

AddNew方法会调用EndEdit方法,并将提交对当前数据的操纵;然后新数据项就成为当前项。

AddNew方法会引发AddingNew事件,可以在此事件中为数据项赋值,或者创建新数据项

private void OnAddingNew(object sender, AddingNewEventArgs e)
{
      e.NewObject = new MyCustomObject();//
}

6.用BindingSource对数据排序、过滤、搜索

6.1 Sort

为Sort属性赋上Sort表达式,可以对数据进行排序

myBindingSource.Sort = "ContactName ASC";//对ContanctName列按ASC进行排序

myBindingSource.Sort = "Region ASC, CompanyName DESC"//先按Region、再按CompanyName排序

6.2 Find

Find方法根据指定属性和关键字进行查找,并返回第一个匹配对象的Index
int index = m_CustomersBindingSource.Find("CompanyName",IBM);//按CompanyName查找IBM
if (index != -1)
{
    myBindingSource.Position = index;//定位BindingSource
}

6.3 Filter

为Filter属性赋上表达式,可以对数据进行过滤

m_CustomersBindingSource.Filter = "Country = 'Germany'";//过滤出Country属性为Germany的数据

7.用Event监控数据

7.1 Event

1)AddingNew

调用AddNew()方法时触发。

2)BindingComplete

当控件完成数据绑定时触发,说明控件已经从数据源中读取当前数据项的值。当BindingSource重新绑定或当前数据项改变时,会触发此事件

注:

  • 当有多个控件绑定到同一数据源时,这个事件会触发多次

3)CurrrentChanged

当前数据项改变时触发此事件。触发此事件的情况如下

  • Position属性改变时
  • 添加、删除数据时
  • DataSource或DataMember属性改变时

4)CurrentItemChanged

当前数据项的值改变时触发

5)DataError

通常输入无效数据时,由CurrencyManage抛出异常,从而触发此事件。

6)PositionChanged

Position属性改变时触发此事件。

7)ListChanged

数据集合改变时触发。触发此事件的情况如下

  • adding, editing, deleting, 或 moving 数据项时

改变那些会影响List行为特征的属性时,如AllowEdit属性

  • 替换List时(绑到新数据源)

8.限制数据修改

BindingSource不仅是数据源与控件间的“桥梁”,同时也是数据源的“看门人”。通过BindingSource,我们可以控制对数据的修改。

BinidingSource的AllowEdit, AllowNew和AllowRemove属性可以控制客户端代码和控件对数据的修改

9.复杂数据类型的Binding

对于String类型的数据,直接Binding到Text控件即可,对于复杂类型有下面几种情况

  • 对于DateTime、Image等类型的数据,它们存储的格式与显示要求并不一致。
  • 有时,你并不想显示客户ID,而是希望显示客户名称
  • 数据库中的Null值

9.1 Binding类

解决以上问题的关键是要理解Binding类,了解它是如何控制数据Binding的过程。

DataTable table = customersDataSet.Customers;

//将TextBox的Text属性Binding到table的CustomerID列
customerIDTextBox.DataBindings.Add("Text", table,"CustomerID", true);

//上面一行代码等同下面两行代码

Binding customerIDBinding = new Binding("Text", table,"CustomerID", true);
customerIDTextBox.DataBindings.Add(customerIDBinding);

从代码可以看出,Binding是数据源(table)和控件(customerIDTextBox)间的中介人,它有以下功能

  • 从数据源取数据,并按照控件要求的数据类型对此数据进行格式化(Formatting),然后传给控件
  • 从控件取数据,并按照数据源的数据类型要求对此数据进行解析(Parsing),然后返回给数据源
  • 自动对数据进行格式转换

9.2Binding类构造函数和属性

Binding构造函数有多个重载版本,下面介绍其重要的参数,这些参数同时存在于Binding对象的属性中。下面介绍中,参数名和属性名都列出来

1)formattingEnabled(属性FormattingEnabled)

  •  
    • true,Binding对象自动在数据源类型和控件要求的类型间进行转换
    • false,反之

2)dataSourceUpdateMode

决定控件上数值的改变在何时提交回数据源

3)nullValue

DBNull、 null和Nullab<T>对应的值。

4)formatString

格式转换

5)formatInfo

一个实现IFormatProvider接口的对象引用,用来自定义格式转换

要了解类型如何转换的,请学习Type Conversions and Format Providers相关内容。关于上面属性的应用,请看下面介绍

9.3基于Binding类的内置机制(属性、参数)进行类型转换

通过Binding类构造时的参数,或属性设置,可以控制它进行类型转换的机制。

1)DateTime

下面先介绍一个DateTime类型的例子,使用DateTimePicker控件

//创建Binding,设置formattingEnabled为true

birthDateTimePicker.DataBindings.Add("Value",m_EmployeesBindingSource, "BirthDate", true);

//设定为使用自定义格式
birthDateTimePicker.Format = DateTimePickerFormat.Custom;

//设定格式
birthDateTimePicker.CustomFormat = "MM/dd/yyyy";

2)Numeric

salaryTextBox.DataBindings.Add("Text", employeesBindingSource,"Salary", true,  DataSourceUpdateMode.OnValidation,"<not specified>", "#.00");

以上代码做了以下处理

  • 设定formattingEnabled为true:代表自动类型转换
  • 设定DataSourceUpdateMode为OnValidation:
  • 设定nullValue为"<not specified>":这些DBNull就显示为,"<not specified>", 同时用户录入,"<not specified>"时,数据值为DBNull
  • 设定formatString为"#.00":数值保留2位小数

9.4. 事件

下面介绍Binding的主要事件,以及如何基于这些事件进行类型转换的控制。

主要事件:

1)Format事件

发生在从数据源获取数据后,控件显示此数据之前。在这个事件里将数据源的数据类型转换为控件要求的数据类型。

2)Parse事件

与Event相反。它发生控件值改变后,数据更新回数据源之前。在这个事件里将控件的数据类型转换为数据源要求的数据类型。

这两个事件为我们控制数据提供了机制,它们都声明为ConvertEventHandler类型,

void ConvertEventHandler(object sender, ConvertEventArgs e);

有两个参数,第二个参数ConvertEventArgs e 提供了我们要formatting和parsing的数据。它有两个属性

  • e.DesiredType是数值要转换的目标类型
  • e.Value是要转换的数值。我们可以替换此Value

9.5. 基于事件的类型转换

9.5.1 处理Format Event

void OnCountryFromFormat(object sender, ConvertEventArgs e)
{
    if (e.Value == null || e.Value == DBNull.Value)
    {
         pictureBox.Image = null;
         return;
    }

    //绑定的是数据源的CountryID字段,因此e.Value返回的ID号,通过此ID号取得对应数据行
    CountriesRow countryRow =    GetCountryRow((int)e.Value);

     //将e.Value赋值为CountryName,从而在控件中显示名称
     e.Value = countryRow.CountryName;
    // 数据转换

    ImageConverter converter = new ImageConverter();
    pictureBox.Image =    converter.ConvertFrom(countryRow.Flag) as Image;
}

9.5.2 处理Format Event

void OnCountryFromParse(object sender, ConvertEventArgs e)
{
// Need to look up the Country information for the country name
ExchangeRatesDataSet.CountriesRow row =
GetCountryRow(e.Value.ToString());
if (row == null)
{
string error = "Country not found";
m_ErrorProvider.SetError(m_CountryFromTextBox, error);
m_CountryFromTextBox.Focus();
throw new ArgumentException(error);
}
e.Value = row.CountryID;
}

10 完成数据编辑

经常会遇到这种情况,你在一个控件中录入或选择一些数据,只有当年离开此控件时,关联的数据才能同步更新。这个问题是由DataRow内部机制决定的。

DataRowView类实现IEditableObject接口,支持对象的事务性编辑(当你确认完成编辑前,可以回滚数据)。我们通过BeginEdit()方法来开始数据编辑,通过EndEdit()方法提交编辑。

不要将DataRowView的EndEdit()与DataSet、DataTable、DataRow的AcceptChanges()方法混淆。DataRow有original和current版本,同时IEditableObject的caching机制让它有transient版本,在调用EndEdit()方法前,数据修改是不会提交到数据源。这就是前面问题的内在原因。

如果希望编辑的数据立即提交,那调用EndEdit()函数的最佳位置就是Validated事件。Validate事件在控件录入的数据parsed,并且通过validate后触发,在这个事件中触发EndEdit()就会通知绑定到同一数据源的所有控件,从而实现数据同步更新。

private void OnCountryTextValidated(object sender, EventArgs e)
{
          exchangeRatesBindingSource.EndEdit();
}

当然,当前数据项改变时,也会触发EndEdit()事件

11 使用AutoComplete

当你希望TexbBox或ComboBox中会自动提示功能,那你应该学习一下AutoComplete功能。下面以TextBox为例介绍相关步骤

1)设定TextBox的AutoCompleteSource属性:FileSystem, HistoryList, RecentlyUsedList

2)如果希望使用自定义的列表,则设定AutoCompleteSource属性为CustomSource

3)设定AutoCompleteMode为SuggestAppend。这意味着你输入部分字符时,控件在下拉列表中提示所有相近的数据

4)如果不想使用内置的提示源,你可以自己创建一个AutoCompleteStringCollection类的列表,

5)创建这个列表后,将它赋给TextBox的AutoCompleteCustomSourc属性

12 DataBinding的生命周期

BindingSource的DataSourceUpdateMode属性是关键,它有以下三种可能值,下面分布以TextBox控件为例介绍此属性不同时DataBinding的生命周期

1)OnValidating(缺省值)

  • DataBinding的生命周期:

TextBox.Leave, TextBox.Validating, Binding.Parse, TextBox.Validated

  • 此时若将控件的CausesValidation属性设为false,那么Validating事件就不会发生

2)OnPropertyChanged

  • DataBinding的生命周期:

此时,每次控件值发生改变时都会触发Binding.Parse。对TextBox控件来说,每次录入字符都会触发Binding.Parse。

3)Never

此时Parse事件不会触发,也就是说控件将成为只读的。

13 子父绑定

前面介绍了主细绑定,它其实是一个父子绑定。有时我们希望由子到父的关联绑定,下面我们就一起来实现这个机制。实现这个机制的关键还是Event,这个Event就是BindingSource的CurrentChanged事件

private void OnCurrentChanged(object sender, EventArgs e)
      {
         // 获取当前的子DataRow
         ExchangeRatesDataSet.ExchangeRatesRow currentRow =
            (ExchangeRatesDataSet.ExchangeRatesRow)
            ((DataRowView)m_ExchangeRatesBindingSource.Current).Row;

         // 获取关联的父DataRow
         ExchangeRatesDataSet.CountriesRow fromCountryRow =
            currentRow.CountriesRowByFK_ExchangeRates_CountriesFrom;
         ExchangeRatesDataSet.CountriesRow toCountryRow =
            currentRow.CountriesRowByFK_ExchangeRates_CountriesTo;

         //显示父DataRow的信息

         if (fromCountryRow != null && toCountryRow != null)
         {
            m_FromCountryCombo.SelectedValue = fromCountryRow.CountryID;
            m_ToCountryCombo.SelectedValue = toCountryRow.CountryID;
         }

}

14 绑定到数据的多个复本

有时,我们希望以不同角度看到同一数据,这时需要绑定到同一数据的多个复本。这里的关键是CurrencyManager类,每个BindingSource管理着一个CurrencyManager。如果多个控件绑定到同一个BindingSource,那么只有一个CurrencyManager,因此也就只有一个CurrentItem,这样就造成这些绑定到同一BindingSource的控件同步刷新。要解决这个问题,我们需要多个CurrencyManager,也就是说我们可以创建多个BindingSource,且绑定到同一个数据源。

 

 

9.5 处理Null类型

这里有两个概念要弄清楚,.Net内置的Null类型与代表数据库中的Null类型,以及它们的区别。

1).Net内置的Null类型

  • Nullable,引用类型
  • Nuallable<T>,值类型

2).Net用来代表数据库中的Null类型

  • DBNull,它有一个属性Value,可以用来判断数据是否为DBNull

          if (northwindDataSet.Employees[0].Country == DBNull.Value)
         {
                 // Handle null case here
          }

         对强类型数据集

if (northwindDataSet.Employees[0].IsCountryNull())
{
// Handle null case here
}

  •  
    •  

         

 

 

 

 

 

 

 

 

 


 

1)AddNew()函数:用来添加一条数据,返回类型由绑定的DataSource决定。

1)绑定到DataSet/DataTable时,返回DataRowView对象。

注意:

      a)返回的不是DataSet或DataTable或DataRow。

      b)如果希望获取添加的数据,需要进行类型转换

           //bs为你创建的BindingSource

          DataRow row=(DataRow)((DataRowView) bs.AddNew()).Row;

       c)使用TypedDataSet时,转换方法与上面类似,只是用TypedDataRow而已

         //MyDataRow为你定义的TypedDataRow

          MyDataRow row=(MyDataRow)((DataRowView) bs.AddNew()).Row;

 

 

 

 

 

 

 

 

 

 

 

 

讨论帖http://topic.csdn.net/u/20090521/20/c5b62beb-9a15-4a61-a439-f57a6870887d.html

 

 

 

 

ataGridView为什么不直接绑定DataTable,而要用BindingSource呢?[问题点数:20,结帖人:zhaigates]

楼主发表于:2009-05-21 20:30:00
如题...
 
 

#1楼 得分:2回复于:2009-05-21 20:35:34
BindingSource 管理与数据源交互的详细信息。
BindingSource 组件可表示任何 Windows 窗体数据源,并在选择或修改数据位置时提供很大的灵活性。
参考
 

#2楼 得分:2回复于:2009-05-21 20:38:35
引用 1 楼 wuyq11 的回复:
BindingSource 管理与数据源交互的详细信息。 
BindingSource 组件可表示任何 Windows 窗体数据源,并在选择或修改数据位置时提供很大的灵活性。 
参考 

不同意楼上的观点我认为,用DataTable来实现绑定比较好,它可以按照我们程序员的思路来解决问题,也满足三层结构,而BindingSource是把数据访问层
和界面层混在一起!
 

#3楼 得分:0回复于:2009-05-21 20:39:17
如果提交数据的话,那么就需要使用bindingSource,因为datagridview可以使用各种数据源,所以它本身是不知道这些数据来自哪儿的。所以就需要一个媒介。bindingSource是钦定的媒介,它一边连接着DataGridView,另一边连接着DataTable。它可以让DataGridView结束编辑状态,同时可以将最新数据提交到DataTable中。
 

#4楼 得分:0回复于:2009-05-21 20:44:56
DataTable 因为有 DataView , 使得使用 BindingSource 的优势不明显.

其实楼主的问题是:

  使用 BindingSouce 而不是使用 DataTable, 获得了哪些好处?
  或者说,
  使用 DataTable 而不用 BindingSource, 我们损失了什么功能?


否则, 一切都是扯淡.


这个问题还真没深入考虑过.
 

#5楼 得分:0回复于:2009-05-21 20:55:23
引用 4 楼 Dobzhansky 的回复:
DataTable 因为有 DataView , 使得使用 BindingSource 的优势不明显.

其实楼主的问题是:

使用 BindingSouce 而不是使用 DataTable, 获得了哪些好处?
或者说,
使用 DataTable 而不用 BindingSource, 我们损失了什么功能?


否则, 一切都是扯淡.


这个问题还真没深入考虑过.

对头
一个DataGridView直接就绑定了一个DataTable,不会更改
不少地方说用BindingSource,但是说的原因有点模棱两可
 

#6楼 得分:0回复于:2009-05-21 21:02:16
引用 3 楼 cxcco 的回复:
如果提交数据的话,那么就需要使用bindingSource,因为datagridview可以使用各种数据源,所以它本身是不知道这些数据来自哪儿的。所以就需要一个媒介。bindingSource是钦定的媒介,它一边连接着DataGridView,另一边连接着DataTable。它可以让DataGridView结束编辑状态,同时可以将最新数据提交到DataTable中。

不对啊!

用DataTable绑定的话,DataGridView可以直接提交的啊!

每次编辑结束,当前的DataGridView的数据就提交了,也就是说DataTable的数据改变了!
 

#7楼 得分:0回复于:2009-05-21 21:02:52
所以我觉得还是用DataTable方便些,直接绑定了!
 

#8楼 得分:0回复于:2009-05-21 21:13:41
偶是这么用的
感觉也很方便...
 

#9楼 得分:16回复于:2009-05-21 21:14:16
DataTable 做数据绑定时, 真正用的是 DataView,

下面就来比较一下 DataView 和 BindingSource:

C# code
public class DataView : MarshalByValueComponent, IBindingListView, IBindingList, IList, ICollection, IEnumerable, ITypedList, ISupportInitializeNotification, ISupportInitialize public class BindingSource : Component, IBindingListView, IBindingList, IList, ICollection, IEnumerable, ITypedList, ICancelAddNew, ISupportInitializeNotification, ISupportInitialize, ICurrencyManagerProvider


可以看出, BindingSource 比 DataView 多实现了一个接口 ICurrencyManagerProvider

通过查看 MSDN 了解到, 这涉及到在数据源层次维护一个当前位置的概念.

尽管我们在界面上可以看到当前记录是哪一个, 但是使用 BindingSource 我们可以直接用它来对数据进行导航,
导航的结果也会反映到 UI 上,
说到导航, 引出 BindingNavigator 类, 而 BindingNavigator 需要的数据源正是一个 BindingSource 类型的.

所以:
  在涉及到数据源当前位置定位以及导航时, BindingSouce 比 DataView 胜出一局.

(注: 使用 DataView 也会自动生成一个 CurrencyManager)
 

#10楼 得分:0回复于:2009-05-21 21:17:41
引用 9 楼 Dobzhansky 的回复:
DataTable 做数据绑定时, 真正用的是 DataView,

下面就来比较一下 DataView 和 BindingSource:

C# codepublicclassDataView : MarshalByValueComponent, IBindingListView, IBindingList, IList, 
ICollection, IEnumerable, ITypedList, ISupportInitializeNotification, ISupportInitializepublicclassBindingSource : Component, IBindingListView, IBindingList, IList, 
ICollection, IEnumerable, ITypedLis…

很详细 学习
 

#11楼 得分:0回复于:2009-05-21 21:23:38
看到国外的一个类似问题的回答
和9楼的几乎一样
The BindingSource class was introduced because people were used to having the notion of a "current" record combined ^with^ the data set.

You can access the current values of the "row" in the BindingSource through the indexer (the same way you would with a DataRow).

If you need to cycle through the rows, you can use the MoveFirst,MoveNext, MoveLast, MovePrevious methods to navigate through the data.

If the possibility of the type of the underlying data source might change, from a design standpoint, it would be better to work with the BindingSource, since that is abstracting the underlying data type.

However, if the underlying data source type is "baked", meaning it will not change, then work with the data set.

I will typically construct my own DataView when working with a DataTable and I need to perform specific sorting or filtering. If I don't have a need for that, then I access the DataSet directly.
 

#12楼 得分:0回复于:2009-05-21 21:31:10
我也一直有这个疑问,用BindingSource后自动生成相应的TableAdapter,筛选、排序、保存数据是方便,但是好像不好用事务,这是一个遗憾,或者我没找到方法,不知大家是怎样做的?
 

#13楼 得分:0回复于:2009-05-21 21:33:33
引用 11 楼 zhaigates 的回复:
看到国外的一个类似问题的回答
和9楼的几乎一样
The BindingSource class was introduced because people were used to having the notion of a "current" record combined ^with^ the data set.

You can access the current values of the "row" in the BindingSource through the indexer (the same way you would with a DataRow).

If you need to cycle through the rows, you can use the MoveFirst,MoveNext, Move…


嘿嘿
 

#14楼 得分:0回复于:2009-05-21 21:34:14
关于数据绑定, 还有一个重要的东西: BindingContext
 

#15楼 得分:0回复于:2009-05-21 21:41:55
datagridview可以使用各种数据源,它本身是不知道这些数据来源
 

#16楼 得分:0回复于:2009-05-21 23:00:32
到还没仔细考虑过。

不过都是直接把datasource设置为datatable了。
 

#17楼 得分:0回复于:2009-05-21 23:13:23
返回一个数据集dataset1丢给datagridview,即
datagridview1.datasource=dataset1.Table[0].Defaultview
 

#18楼 得分:0回复于:2009-05-21 23:29:34
说个简单的例子,lz可以直接把一个list<t>绑给datagridview,试着删除一下看看,你会发现报错哦,而如果通过binddatasource多了这个中转后,很多工作它可以帮助你来完成,实现前面的效果就会很简单.
 

#19楼 得分:0回复于:2009-05-22 08:37:15
好帖子,值得收藏.....
 

#20楼 得分:0回复于:2009-05-22 09:00:22
不使用 BindingSource 作为控件和基础数据源的中间层也行,但是 BindingSource 在很多时候非常有价值 这里只展示了一个很小的方面。

1. ListControl.DataSource 属性

获取或设置此 ListControl 的数据源。实现 IList 或 IListSource 接口的对象可以作为数据源,如 DataSet 或 Array。

假设现在有两个对象:List<T> 的 mylist,ListBox 类型的 listBox1。下面这条语句可以使 mylist 的内容显示到 listBox1 中(方法一):

listBox1.DataSource = mylist;

2. BindingSource 类

封装窗体的数据源。BindingSoiurce 实现的接口有:Component, IBindingListView, IBindingList, IList, ICollecti
  • 从数据源取数据,并按照控件要求的数据类型对此数据进行格式化(Formatting),然后传给控件
  • 从控件取数据,并按照数据源的数据类型要求对此数据进行解析(Parsing),然后返回给数据源
  • 自动对数据进行格式转换on, IEnumerable, ITypedList, ICancelAddNew, ISupportInitializeNotification, ISupportInitialize, ICurrencyManagerProvider。

    假设现在还有一个 BindingSource 对象 bsrc ,下面的语句也可以使 mylist 的内容显示到 listBox1 中(方法二):

    bsrc = new BindingSource(mylist, null);
    listBox1.DataSource = bsrc;

    3. 为什么需要 BindingSource ?

    先看看 BindingSource 除了让控件知道从哪儿读取数据,还能做什么:

    它通过提供一个间接寻址层、当前项管理、更改通知和其他服务简化了窗体中控件到数据的绑定。这是通过将 BindingSource 组件附加到数据源然后将窗体中的控件绑定到 BindingSource 组件来实现的。与数据的所有进一步交互,包括定位、排序、筛选和更新,都通过调用 BindingSource 组件实现。
    值得注意的最后一句话,我在《对象引用的保护措施》中提出的“包装类”方案就是想让包装类做到这样。

    总之,BindingSource 可以监视(直观地说是“监视”,本质上是“代理”)数据源的变化。在上面的方法一中,listBox1 不能跟踪 mylist 的变化,比如由这条语句引起的数据变更:

    mylist.RemoveAt(3);  
    如果要让 listBox1 反应 mylist 的最新情况,需要:

    listBox1.DataSource = null;  
    listBox1.DataSource = mylist;  
    或其它可以使 listBox1 与 mylist "从头开始"的语句。

    From:http://home.aaaad.cn/space.php?uid=56673&do=blog&id=14667
  •  

     

     

                              dataGridView1.EndEdit()                                        bsData.EndEdit()

    datagridview<---------------------------------->  bindingsource  <-------------------------------------------->  datatable

                              数据传递                                                                   数据传递

     

     

     

    1.是  桥梁  开关 控制的作用

    2.数据源 与  控件之间的转换

     

    《未完》

     

     

     

    0
    0

    查看评论
    * 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
      个人资料
      • 访问:96013次
      • 积分:1302
      • 等级:
      • 排名:千里之外
      • 原创:31篇
      • 转载:8篇
      • 译文:1篇
      • 评论:5条
      最新评论