前言

 

在上篇写了篇
实战系列之天气预报实时采集
,有独家同志认为并未技术含量,也许恰恰使所说。

单单是食指每出眼光,当自己形容有同样篇稿子时,我只是要:

1:如果你还未晓,请圈写法,了解想法

2:如果您都解,略过写法,请圈想尽

 

事实上纵观我直接写来的200多篇稿子,基本还足以望那点划痕:

同一:没有水文

老二:没有华丽理论型的篇章

老三:实战型文章很多

季:文章尽量面向新手的达,尽量了

 

今勾勒首,还是打算从简入手,希望新手也会发取,有发没“技术含量”,大伙看正在说了~~~要是看不知道,你虽接触下推荐图片 1~

 

以下为正文

 

平等:Winform下的DataGridView不支持以DataReader绑定

1:问题时有发生

在 CYQ.Data
框架 进行到V1.5本子要支持Winform时,曾遇到一个题材,就是心有余而力不足绑定DataGridView。

 

2:思考分析试验

MDataTable走的是DataReader方式实现的绑定,除非DataReader无法绑定DataGridView,不然就是自己实现有题目。

于是,做只考试:使用SqlDataReader直接绑定Winform下之DataGridView,发现黄了。

于是大方追寻,发现DataReader实在无法直接绑定DataGridView,通过数据源控件中转绑定的尽管到底了。

 

3:得出结论

DataReader方式都爱莫能助绑定Winform下的DataGridView,我当时前赴后继的DataReader的实现方式吗就是重新未能实现绑定了。

只好另寻计-》DataGridView支持DataTable,于是使于DataTable入手了。

 

二:DataTable很强大,支持Web又支持Winform

 

1:分析绑定原理

于此前的MDataTable实现绑定原理篇中,我们研究来而促成绑定,有少种植方法:

平种是贯彻IEnumerable接口,即当初动之DataReader方式实现之绑定。

外一样栽是兑现IListSource接口,即走DataTable方式贯彻之绑定。

为甚当初勿实现DataTable方式的绑定,不纵得了了,两栽都支持~~-_-..本以得回来折腾IListSource接口的贯彻

 

2:深入DataTable绑定原理

咱通过Reflector反编绎看下DataTable继承实现之接口:

public class DataTable : MarshalByValueComponent, IListSource, ISupportInitializeNotification, ISupportInitialize, ISerializable, IXmlSerializable

差一点都是咱们平常从不因此到之接口,不理先,我们关心IListSource怎么落实绑定的。

假设协调拘留一下IListSource设实现之接口有几乎独道:

public interface IListSource
{
    // Methods
    IList GetList();
    // Properties
    bool ContainsListCollection { get; }
}

虽简单单,太爱了,接着我们如果当DataTable
6000大多推行之代码中找到IListSource的实现,查找是太好之点子:

//DataTable的实现
bool IListSource.ContainsListCollection
{
    get {  return false; }

}

IList IListSource.GetList()
{
    return this.DefaultView;
}

GetList接口没事就赶回了单默认视图,又如绝对进看视图了。

图片 2图片 3

public DataView DefaultView
{
    get
    {
        DataView defaultView = this.defaultView;
        if (defaultView == null)
        {
            if (this.dataSet != null)
            {
                defaultView = this.dataSet.DefaultViewManager.CreateDataView(this);
            }
            else
            {
                defaultView = new DataView(this, true);
                defaultView.SetIndex2(“”, DataViewRowState.CurrentRows, null, true);
            }
            defaultView = Interlocked.CompareExchange<DataView>(ref this.defaultView, defaultView, null);
            if (defaultView == null)
            {
                defaultView = this.defaultView;
            }
        }
        return defaultView;
    }
}

决进就一样大堆,实在没有心思看下去,省略中间看身材与尾,只了解回了单DataView。

public class DataView : MarshalByValueComponent, IBindingListView, IBindingList, IList, ICollection, IEnumerable, ITypedList, ISupportInitializeNotification, ISupportInitialize

忽悠:

并且是神马般的同一积接口,内部代码太多,实在没有情绪看;
自不过想明白IListSource怎么落实绑定,至于另外有平等积聚没一堆放的自身一向无关注,我一旦我眷恋如果之。
扫了扳平双眼接口,发现是继续了IList,这同IListSource要求的回来值IList是一样的。

 

神马啊神马,没点头绪,完全摸不交绑定的首要,难道说,随便找找个IList返回的接近即执行了?

于是让MDataTable实现IListSource接口,试试看:

public class MDataTable : IDataReader, IEnumerable,System.ComponentModel.IListSource

心想事成接口:

public IList GetList()
{
    return Rows;
}

随着忽悠:

好说自的Rows也是累自List<xxx>的,试着绑定结果很潇洒,出来了不是本身设想
连续折腾DataView,传说DataView也会直接绑定控件的,yo~~有平等丝想法

 

于是乎看一下其落实IList接口的源码,发现一律积聚都在操作DataRowView

public class DataRowView : ICustomTypeDescriptor, IEditableObject, IDataErrorInfo, INotifyPropertyChanged

无奈忽悠了:

乃只XX,从DataTable-》DataView-》DataRowView,再变更自头就是晕了~~
并且是一律堆死生疏的接口,于是到此处,我几已了步子,因为自分析不下了~~

 

上WC仔细从头想了:

于IList<实体>绑定,所有的性能都见面被当是列名,其值为行的价值。

假定对此DataTable,里面又是怎认识有列名和剖析出值的也罢?

1:从DataTable中,我们看同样丝列名提取的相干办法,只是返回->DataRow
2:从DataRow中吗看不到提取列名的法,其主体的IList接口的相干落实引出了->DataRowView
3:DataRowView?是秘密的四面八方?一积聚继承的接口也是死陌生

 

回头继续搜寻:

更换思路继续大量找:换了重重要字,搜中文又搜E文

结果总是相同积聚自定义控件开发之东东,结果印象中当某某平等篇之googleE文的“网页快照”中发觉相同截E文,

原文不知是哪了,上次且记得只能打开快照,现在估算会快照都未曾了,按想象翻译下的中文大致为:

DataTable能实现该绑定,是以其落实了ICustomTypeDescriptor,从而赢得该性能

 

偶滴神啊~能从宏伟的E文中,扫到几个至关重要字不轻呀!!!

假若反过来过头看上面的DataRowView,就会意识,正好,它实现了接口ICustomTypeDescriptor,
惟有是遥想当年,我连无像今天写文这么冷清,我当场早把Reflector关掉了,哪还记DataRowView实现了ICustomTypeDescriptor,
更何况ICustomTypeDescriptor对自己以是那的生,是那么的素不相识,…很生疏。。。

 

潜在就出去了

ICustomTypeDescriptor接口,一个动控件开发人员经常应酬的接口,对于咱们却极为陌生的接口

是它,就是她,就是其实现怎样识别哪些是列名,哪些是列值。

 

 

3:浅入ICustomTypeDescriptor

当初自经过大量底检索,试图找到相关的使示范,因为那时候我非理解DataRowView,要是知道,我虽毫无那么辛苦去搜文章了。

比方你找是接口,你晤面意识一堆的文章还是说走控件开发,我虽打活动控件开发中老辛苦的打通了碰示例实现了。

但此文就未走弯路了,直接解析DataRowView,对于 ICustomTypeDescriptor接口,有为数不少术:

图片 4图片 5

public interface ICustomTypeDescriptor
{
    // Methods
    AttributeCollection GetAttributes();
    string GetClassName();
    string GetComponentName();
    TypeConverter GetConverter();
    EventDescriptor GetDefaultEvent();
    PropertyDescriptor GetDefaultProperty();
    object GetEditor(Type editorBaseType);
    EventDescriptorCollection GetEvents();
    EventDescriptorCollection GetEvents(Attribute[] attributes);
    PropertyDescriptorCollection GetProperties();
    PropertyDescriptorCollection GetProperties(Attribute[] attributes);
    object GetPropertyOwner(PropertyDescriptor pd);
}

可是基本是摆放,只为用无至,除了一个接口方法:GetProperties:System.ComponentModel.PropertyDescriptorCollection)(Attribute[]
attributes)

遂我们解析DataRowView对是接口的实现:

图片 6图片 7

PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
    if (this.dataView.Table == null)
    {
        return zeroPropertyDescriptorCollection;
    }
    return this.dataView.Table.GetPropertyDescriptorCollection(attributes);
}

持续深入:

图片 8图片 9

internal PropertyDescriptorCollection GetPropertyDescriptorCollection(Attribute[] attributes)
{
    if (this.propertyDescriptorCollectionCache == null)
    {
        int count = this.Columns.Count;
        int num4 = this.ChildRelations.Count;
        PropertyDescriptor[] properties = new PropertyDescriptor[count + num4];
        for (int i = 0; i < count; i++)
        {
            properties[i] = new DataColumnPropertyDescriptor(this.Columns[i]);
        }
        for (int j = 0; j < num4; j++)
        {
            properties[count + j] = new DataRelationPropertyDescriptor(this.ChildRelations[j]);
        }
        this.propertyDescriptorCollectionCache = new PropertyDescriptorCollection(properties);
    }
    return this.propertyDescriptorCollectionCache;
}

 

关键定位,只是返回一组:DataColumnPropertyDescriptor)

那DataColumnPropertyDescriptor)是啊?继续深入:

internal DataColumnPropertyDescriptor(DataColumn dataColumn) : base(dataColumn.ColumnName, null)
{
    this.column = dataColumn;
}

区区实行代码,那个base是什么?是PropertyDescriptor) ,实现充分简单,把列名传过去便尽了,至此,就结了。

 

非明了出小会看到这里,估计本文大伙也就是是扫下来,除非有天若用到,不然只是忽悠下眼球了。

 

总下实际实现ICustomTypeDescriptor接口方法:

1:继承实现接口方法
2:重点实现GetProperties(Attribute[] attributes)方法
3:需要打定义属性描述类,而立起定义之性能描述类需要继续自抽象基类PropertyDescriptor
4:GetProperties返回的是由定义属性描述类的聚众

 

其三:绑定原理分析了,MDataTable模仿出击

 

1:MDataTable继承IListSource接口落实

图片 10图片 11

       #region IListSource 成员
        public bool ContainsListCollection
        {
            get
            {
                return true;
            }
        }
        public IList GetList()
        {
            return Rows;
        }
        #endregion

 

2:MDataRow继承ICustomTypeDescriptor接口实现

A:先实现由定义属性描述类

图片 12图片 13从定义属性描述类MDataProperty

internal class MDataProperty : System.ComponentModel.PropertyDescriptor
    {
        private MDataCell cell = null;
        public MDataProperty(MDataCell mdc, Attribute[] attrs)
            : base(mdc._CellStruct.ColumnName, attrs)
        {
            cell = mdc;
        }

        public override bool CanResetValue(object component)
        {
            return false;
        }

        public override Type ComponentType
        {
            get
            {
                return typeof(MDataCell);
            }
        }
        public override object GetValue(object component)
        {
            return ((MDataRow)component)[cell._CellStruct.ColumnName].Value;
           
        }

        public override bool IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public override Type PropertyType
        {
            get { return cell._CellStruct.ValueType; }
        }

        public override void ResetValue(object component)
        {

        }

        public override void SetValue(object component, object value)
        {
            cell.Value = value;
        }

        public override bool ShouldSerializeValue(object component)
        {
            return true;
        }
              
        public override bool IsBrowsable
        {
            get
            {
                return true;
            }
        }
    }

 

B:实现重点措施GetProperties(Attribute[]
attributes)

图片 14图片 15

        int index = 0;
        PropertyDescriptorCollection properties;
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            if (index == 1)
            {
                return properties;
            }
            index++;
            properties = new PropertyDescriptorCollection(null);

            foreach (MDataCell mdc in this)
            {
                properties.Add(new MDataProperty(mdc, null));
            }
            return properties;
        }

 

OK,此届,MDataTable顺利完成了针对性Winform下DataGridView的支撑。

 

本文原题:CYQ.Data 轻量数据层之路 MDataTable绑定Winform之DataGridView
原理高级篇(三十一)

 

四:总结

微软很有力,MB的Silverlight不支持DataTable的绑定,难道自己而比方失去追随?研究其绑定本质?

未赶了,MDataTable增加了ToJson方法及ToList<实体>方法,可径直用json传过去再也就此反json系列化解析成List<实体>型就足以一直绑定了。

 

 

正文有接触长,不知发生几乎丁,看之领悟,看的仔细,估计还是刷的霎时从头拉到条了图片 16~~~~ 

相关文章

网站地图xml地图