zoukankan      html  css  js  c++  java
  • .NET各大平台数据列表控件绑定原理及比较(WebForm、Winform、WPF)

    .NET各大平台数据列表控件绑定原理及比较(WebForm、Winform、WPF

    WebForm 下的列表绑定控件基本就是GridView、DataList、Repeater;当然还有其它DropDownList、ListBox等。
    复制代码

     

     

    它们的共同的设置数据源方法:

     

    复制代码
    XXX.DataSource=数据源。
    复制代码

     

     

    那么这个数据源的格式,究竟有啥要求?最简单的方式是随便给弄个,然后等它抛异常:

     

     

     

     

    从上面的错误可以看的出来,基本上支持三种数据源绑定方式:IListSource,IEnumerable,IDataSource。

     

     

    说说Winform

     

    数据列表控件:

     

    复制代码
    WinForm 下的列表绑定控件基本就是DataGridView、ListView、ComboBox等。
    复制代码

     

     

    它们的共同的设置数据源方法:

     

    复制代码
    XXX.DataSource=数据源。 
    复制代码

     

     

    用同样的方式,发现它是死活不抛异常的,通过对DataGridView的DataSource查看代码:

     

     

     一个不够再看一下ComboBox的DataSource:

     

     

     

    从以上的提示可以得到信息,数据源支持:IListSource接口。

     

     

    看看WPF

     

    数据列表控件:

     

    复制代码
    WPF 下的列表绑定控件基本就是DataGrid、ListBox、ComboBox等。
    复制代码

     

     

    它们的共同的设置数据源方法:

     

    复制代码
    XXX.ItemsSource=数据源。 
    复制代码

     

     

    对于WPF,它的ItemsSource不再是Object类型,而是IEnumerable:

     

    从以上的提示可以得到信息,数据源支持:IEnumerable接口。

     

    三者比较:

     

    WebForm: IListSource,IEnumerable,IDataSource。

     

    Winform: IListSource

     

    WPF:   IEnumerable

     

     

    共同点:

     

    复制代码

    由于IListSource的接口有个必须的实现是返回IList,而IList接口本身也有继承自IEnumerable接口。

    所以最终的共同点就是都IEnumerable接口,通俗的说就是都支持:List<T>集合这样的数据源。

    复制代码

     

     

    不同点:(以IDataReader,DataTable,DataSet等通用集合来说明)

     

    复制代码

    WebForm:支持IDataReader,DataTable,DataSet。

    Winform:不支持IDataReader, 支持DataTable,DataSet。 

    WPF:支持IDataReader,不支持DataTable,DataSet。

    复制代码

     

     

    这里面又有些故事:

     

     

    Winform:为虾米不支持IDataReader?

     

    复制代码

    对于DataGridView列表控件,其实表格是可以直接修改的,而且修改的值,会直接返改到绑定的数据源上。

    可能出于这种性质,对于只读的IDataReader来说,它不太适合DataGridView控件上的读写双需求,所以不支持。

    复制代码

     

     

    Winform下的DataTable绑定:

     

    复制代码

    对于List<T>,可以方便的修改集合的属性,而对于DataTable,这是个复杂的自定义类,要绑定的东西并不是表的基本属性,而是存在另一个集合DataRowCollection中。

    所以,设计人员搞出了:PropertyDescriptor 和ICustomTypeDescriptor等一套规范来实现属性描述和自定义类的取值绑定问题。

    复制代码

     

     

    WPF:竟然不考虑DataTable支持:

     

    复制代码
    估计双方没沟通好,或者是考虑到新的DataGrid又返朴归真,去掉了写的需求,WPF竟然不支持DataTable, 好在还有个属性DefaultView,可以把信息读到类似集合的DataTableView再去绑定,虽然多转了一步,但也算是勉强支持绑定了。
    复制代码


     

    再说MDataTable

     

    MDataTable是CYQ.Data 数据层框架里极重要的一组类,实现了和数据库间的完整映射,同时也肩负着和各种UI打交道,当然了,没有它我也不可能去研究各种绑定了。

     

    复制代码

    对于自定义MDataTable数据源,在绑定列表控件的这条路上,几年前我研究了很久,后来最稳定的实现为:

    public class MDataTable : IDataReader, IEnumerable,IListSource

    复制代码

     

     

    为何MDataTable在WPF下和DataTable一样失效了?

     

    复制代码
    这里其实有一个和DataTable不同的东西,就是我的自定义数据源继承了IDataReader和IEnumerable,简单的说是支持WPF的。
    复制代码

     

     

    但是结果为啥绑定无效? 

     

    复制代码
    经过代码调试,发现了原来是接口的优先级问题热的祸, IListSource的级别比IEnumerable的先被调用了,结果就走了类似DataTable那一套规则,但那一套规则的属性读取和WPF是无效的,结果就变成了属性绑定,而不是数据行绑定。
    复制代码

     

     

    解决的办法:

     

    复制代码

    由于IListSource的存在,会导致WPF无法正常绑定,那就把这接口去掉了,发现WPF就正常了。

    但是问题又来了,Winform是靠IListSource接口才能绑定,去掉了IListSource,在winform下不正常了。

    经过一番深思,考虑了DataTable依靠DataTableView的方式来绑定WPF,我亮出了一招:

    复制代码

     

     

     

     

    说明:

     

    复制代码
    把IListSource接口的实现,分到了另一个类 MDataTableView,注意修饰为内部类,说明对于使用者来说,一切是还是照旧,但是内部在MDataTable.Bind方法调用是有识别当前的平台,如果是Winform,则把对象变更为:new MDataTableView(ref sourceObje)
    复制代码

     

     

    总结:

     

    虽然各位平时和这些列表控件相依为命,但估计研究绑定机制的,还是比较少的,毕竟需要一定的缘分。

     

    今天的内容就当个参考,待某天缘分来的时候,有需要的时候,再来回顾我这篇文章亦可。 

  • 相关阅读:
    .NET 2.0泛型集合类与.NET 1.1集合类的区别(二)
    关于插件的好文章
    MemberInfo.GetCustomAttributes和MemberDescriptor.Attributes获取特性的不同
    新一代编程语言
    .NET 2.0泛型集合类与.NET 1.1集合类的区别(一)
    发现一篇关于.NET 2.0中关于事务命名空间的好文章
    C# WinForm控件美化扩展系列之给TextBox加水印
    log4.net
    C# GDI+ 双缓冲
    C# WinForm控件美化扩展系列之ListBox
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3251964.html
Copyright © 2011-2022 走看看