DataTable depth advanced version of the principles of analytical data source bindings

Foreword

 

Wrote a chapter on the weather forecast combat series of real-time collection , there are some comrades we believe that no technical content, perhaps as said.

But people have their own opinion, when I write an article, I just want to:

1: If you do not know, look at the wording, understand the idea of

2: If you already know, skip the wording, see ideas

 

In fact Throughout I have been written by more than 200 articles, the basic point that we can see traces:

A: No Hydrology

II: no fancy theory type of article

III: combat type article number

four: Try for the article expressed the novice, try the

 

Today, write articles, or trying to be a simple start, hope novices can be fruitful, there is there is no "technical content", and everyone looked at to say ~~~ If not read, you can point the recommendation -

 

The following is the text

 

A: Winform DataGridView under binding does not support the use of DataReader

1: problems

In  CYQ.Data frame  when the V1.5 version to support Winform, I had encountered a problem that can not be bound DataGridView.

 

2: thinking and analysis test

MDataTable taking the DataReader way to achieve binding, unless DataReader can not bind DataGridView, or else achieve their own problems.

Therefore, a test: use SqlDataReader directly under the binding DataGridView Winform, discovery failed.

So a lot of searching, found DataReader really can not bind DataGridView directly, by binding the data source control transit even if the.

 

3: concluded

DataReader methods are not binding under DataGridView Winform, my DataReader implementation of the succession it is even more impossible to achieve bound.

I had to find another method - "DataGridView support DataTable, DataTable so from the start.

 

Two: DataTable very powerful, Web-enabled and support Winform

 

1: Analysis of binding principles

Achieve binding principle in the previous chapter MDataTable, we have developed to achieve the binding, there are two ways:

one is to achieve IEnumerable interface, that had to go DataReader way to achieve binding.

Another is to achieve IListSource interface, that bind the DataTable way to go to achieve.

Why did not implement binding DataTable way, not to be lost, both of which are in support of ~ ~ -_- .. and now they have to go back and toss IListSource interface

 

2: In-depth DataTable binding principle

We Reflector Anti unravel look DataTable inherited interface implementation:

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

We usually useless to almost all of the interface, ignore the first, we focus on how to achieve IListSource binding.

If they look at IListSource to implement interfaces are a few ways:

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

On two, too easy, then we have to find IListSource achieve in the code DataTable 6000 multi-line, look for the best way:

// achieve the DataTable BOOL  IListSource.ContainsListCollection { GET  {   return to false ;}


    
 
}

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

GetList nothing on the interface returns a default view, but also cut into it to see the view.

05233300_alBh.gif
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;
    }
}

Cut into it a lot, really not in the mood Read on to see Omitted head and tail, only know that a return to a DataView.

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

Fudge:

God is a bunch of horse-like interfaces, internal code too much, really not in the mood to see;
I just want to know how to achieve IListSource binding, as did a bunch of a bunch of other I do not care, I just want what I want.
He glanced at the interface IList found to be inherited, and this IListSource return value is consistent with the requirements of the IList.

 

Ah God, God Ma Ma, no point clue, could not find focus bound, we say, just to find a class IList returned on the line?

So let MDataTable achieve IListSource interfaces, try:

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

Implement an interface:

public  IList GetList()
{
    
return  Rows;
}

Then Fudge:

I say the Rows is inherited from List < xxx > , try to bind ~~ result is very elegant, it is completely not what I imagine ~~
inherited toss DataView, the legendary DataView can also directly bound controls, yo ~~ a hint idea

 

So look at its source code that implements the IList interface, found in a pile of operation DataRowView

public   class  DataRowView : ICustomTypeDescriptor, IEditableObject, IDataErrorInfo, INotifyPropertyChanged

Not fooled:

You were XX, from DataTable- "DataView-" DataRowView, sub-head I fainted ~ ~
is a bunch of very strange interface, then to here, I almost stopped in her tracks, because I do not go ~~ analysis

 

WC on careful thought from the beginning:

For IList <entities> binding properties are all considered to be a column name, which is the value of the line.

For DataTable, which is how you know a column name and analyze the value of it?

1: From the DataTable, we see a correlation method Siliemingti taken, just return -> DataRow
2: from DataRow also see the method could extract the column names, its key associated IList implementation leads -> DataRowView
3: DataRowView? Is where the mystery? A bunch of inherited interface is also very strange

 

Continue to search back:

Convert ideas continue to exhaustively search: for a lot of keyword search Chinese and E-text search

The result is full of a bunch of custom control development of the East, the impression that the results found in the text of paragraph E "Cached" googleE a certain text in,

I do not know what the original, open only remember the last time snapshots, now estimated to snapshots gone, according to the imagination of the Chinese translated roughly as follows:

DataTable to achieve its binding, because it implements ICustomTypeDescriptor, to obtain its properties

 

Oudi God ~ E from the mighty force of the text, to sweep a few keywords not easy! ! !

If you go back and look at the above DataRowView, you will find, just that it implements the interface ICustomTypeDescriptor,
but way back when, I do not write the text as it is now so cool, I had put his Reflector turned off, which also remember DataRowView realized ICustomTypeDescriptor ,
say ICustomTypeDescriptor to me is so strange, so strange, very strange .... . .

 

The secret is out

ICustomTypeDescriptor interface, the interface a mobile control developers often dealing, for we are very familiar interface

is it, is it, is it realize how to identify what is the name of the column, which is column values.

 

 

3:浅入ICustomTypeDescriptor

When I pass a lot of searching, trying to find the relevant application examples, because I did not know DataRowView, if you know, I would not be so hard to search the article.

If you search this interface, you'll find a bunch of articles are said to develop mobile controls, I am from a mobile control development dig very hard to achieve a point example.

However, this time no detours, direct analysis DataRowView, for  ICustomTypeDescriptor interfaces, there are many ways:

05233300_alBh.gif
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);
}

But the basic furnishings, because less than, except one interface method: GetProperties ( the Attribute [] Attributes)

So we realize DataRowView analysis of this interface:

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

Continue in-depth:

05233300_alBh.gif
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;
}

 

The key location, just return a set: DataColumnPropertyDescriptor

That DataColumnPropertyDescriptor what is? Continue in-depth:

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

Two lines of code, the base is what? It is PropertyDescriptor  , very simple to achieve, the column name to last on the list, so far, is over.

 

I do not know how many will see here, it is estimated this article everyone is swept down, unless you want to apply to the day, or just under the flicker of the eye.

 

ICustomTypeDescriptor interface methods to achieve specific case summary:

1 : Inheritance implement interface method
2 : Key implement GetProperties (Attribute [] attributes) Method
3 : requires custom properties described class, which customize the properties described in the class definition need to inherit from the abstract base class for the PropertyDescriptor
. 4 : GetProperties returns custom collection of attributes that describes the classes

 

Three: After analyzing the binding principle, MDataTable imitate attack

 

1: MDataTable interface inheritance IListSource

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

 

2: MDataRow inherited ICustomTypeDescriptor interface

A: First implement custom class attribute description

05233300_alBh.gif Custom properties described class 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: Key implemented method GetProperties (Attribute [] attributes)

05233300_alBh.gif
         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, this to, MDataTable support for the successful completion of the DataGridView Winform under.

 

This article Original title: CYQ.Data Road, lightweight data layers MDataTable bind DataGridView Winform principle advanced part of the (31)

 

Four: summary

Microsoft is very powerful, MB Silverlight does not support binding the DataTable, do I have to go to follow? Study its binding nature?

Do not chase, MDataTable increased ToJson method and ToList
< Entity > method can be resolved directly with anti-json json serialization and then pass in the past to List < Entity > type can be directly bound.

 

 

This article is a bit long, I do not know a few people, see and understand, look carefully, brush look from scratch is estimated to pull the tail ~~~~ 

Reproduced in: https: //my.oschina.net/secyaher/blog/274109

Guess you like

Origin blog.csdn.net/weixin_34301307/article/details/91966757