Set of classes representing business data layer.

Classes

  ClassDescription
Public classCompositeFieldAttribute
Indicates that the property of business object is composite.
Public classCompositeObjectAccessor
Accessor to composite data objects
Public classCustomTypeDescriptorAccessor
Wraps an object the ICustomTypeDescriptor type.
Public classDataObjectAccessor
Wraps an object of arbitrary class and provides access to it via reflection. Can be a part of event-driven model.
Public classDataObjectAccessorBase
Base data accessor
Public classDataRowAccessor
Wraps an object of the DataRow type.
Public classDictionaryDataAccessor
Public classFieldAttribute
Sets a specific property identifier for user-defined classes.
Public classFieldChangedEventArgs
Contains information about updated IDataField
Public classGetter<(Of <(<'T>)>)>
Gets a value of a data object property
Public classHierarchicalDataAccessor
Provides an access to data containing hierarchical fields
Public classHierarchicalFieldAttribute
Indicates that a property in a user-defined class should be interpreted as the hierarchical field
Public classListDataAccessor
Wraps IList objects.
Public classPrimitiveTypeAccessor
Wraps primitive object types such as int, double, etc...
Public classThreadSafeBindingList<(Of <(<'T>)>)>
Threadsafe implementation of BindingList<(Of <(<'T>)>)>
Public classUnboundValueAccessor
Collection of IDataField objects that is populated when GridControl requires data fields.

Interfaces

  InterfaceDescription
Public interfaceIDataAccessor
Collection of IDataField. Normalizes presentation of different data types in GridControl
Public interfaceIDataField
Field of IDataAccessor. Typically, this interface represents a property of a data object, a value in a collection, etc.
Public interfaceIGetAccelerator
A cache that keep a value returned from data object property.
Public interfaceIGetter
Gets a value of a data object property

Delegates

  DelegateDescription
Public delegateGetter<(Of <(<'T>)>)>..::..GetterDelegate
A delegate that gets property value.

Remarks

GridControl is able to manipulate various data types, including user defined classes, string arrays or other objects, IList<(Of <(<'T>)>)>, IDictionary<(Of <(<'TKey, TValue>)>)>, where K is a string identifier or some other type. As you remember, all this broad range of data can be inserted into the Wpf GridControl through the GridControl.Rows.Add(object) / Row.Add(object). Besides that, the grid can be connected to a data source that implements IList, IListSource or IBindingList interfaces.

Such broad functionality of the Wpf GridControl is possible due to the IDataAccessor interface that is one of the most crucial part of the grid. The main purpose of this interface is to normalize presentation of different data types in the grid. There are lots of implementations of IDataAccessor interface. This way, a programmer can add his own implementation to broaden the list of data types that can be used by the Wpf GridControl. When you call GridControl.Rows.Add(object 'your object'), an implementation of the IDataAccessor interface is created implicitly for 'your object' and the Wpf GridControl works with it only via the IDataAccessor proxy, making no difference between the data types.

Intrinsically, IDataAccessor interface is nothing more than a simple 'container' for data object fields (IDataField object), that should be displayed in a grid cell. Each field contains an identifier, a name, a description, information about formats and editors, and it can be used to get values from a data object or to set values. Please note, that for different objects the process of getting or setting values of a data object may vary. For user-defined classes you can use the reflection mechanism to get or set values. For IList<(Of <(<'T>)>)> the grid gets them with a certain index; for IDictionary<string, object> with a string key so on. IDataAccessor may support or not support data field identifiers it merely depends on its nature. If an object of user defined class is inserted into the grid, than its property name become the identifiers in the IDataAccessor by default. However, sometimes identifiers may be absent, e.g. if you you use an IList<(Of <(<'T>)>)> object as a parameter of the method GridControl.Rows.Add(object 'your object'). In such case, to display data in cells the Wpf GridControl uses indexes of IList<(Of <(<'T>)>)> and index of the column which is calculated when it is inserted into the header.

IDataAccessor is able to subscribe to events of data objects implementing INotifyPropertyChanged interface and transfer them into the grid. This approach is widely used in the event-driven model. Please note, that all implementations of the IDataAccessor interface in the Dapfor's package are thread-safe!

 Copy imageCopy
public void DataLevelAbstraction(GridControl grid)
{
    //Initialize the header
    grid.Headers.Add(new Header());
    grid.Headers[0].Add(new Column("Price"));
    grid.Headers[0].Add(new Column("Quantity"));

    //Add a data object to the grid. The object is implicitly wrapped by the DataObjectAccessor
    Product product = new Product();
    grid.Rows.Add(new Product());

    //Add a data object which is explicitly wrapped by the DataObjectAccessor to the grid. 
    grid.Rows.Add(new DataObjectAccessor(new Product()));

    //Add a collection of values to the grid. 
    //Because of this collection implements IList, it will be implicitly wrapped by the ListDataAccessor
    grid.Rows.Add(new double[] {123, 12, 45});

    //Add a dictionary of values to the grid. 
    Hashtable hashTable = new Hashtable();
    hashTable.Add("Price", 10);
    grid.Rows.Add(hashTable);

    //Add an empty row to the grid
    Row row = grid.Rows.Add(new UnboundValueAccessor());

    //Set some values for this row
    row["Price"].Value = 10;

    //Build some hierarchy for the already added row
    row.Add(new int[] {10, 11, 12});


    //Now we will update the product. The property of Product fires the notification 
    //and the grid will automatically refresh the cell, scroll and filter corresponding row if needed.
    product.Price = 98.6;

    //Update the product in other thread - this is safe. The grid will synchronize threads without blocking the calling thread
    //and refresh, sort and filter the corresponding row.
    ThreadPool.QueueUserWorkItem(delegate
    {
        product.Price = 102.7;
    });
}