Accessor to composite data objects
Namespace: Dapfor.Wpf.DataAssembly: Dapfor.Wpf (in Dapfor.Wpf.dll) Version: 4.1.0.26317 (4.1.0.26317)
Syntax
C# |
---|
public class CompositeObjectAccessor : IDataAccessor, IEnumerable<IDataField>, IEnumerable |
Visual Basic |
---|
Public Class CompositeObjectAccessor Implements IDataAccessor, IEnumerable(Of IDataField), IEnumerable |
Visual C++ |
---|
public ref class CompositeObjectAccessor : IDataAccessor, IEnumerable<IDataField^>, IEnumerable |
F# |
---|
type CompositeObjectAccessor = class interface IDataAccessor interface IEnumerable<IDataField> interface IEnumerable end |
Remarks
Continuing the idea of declarative data binding, Dapfor has implemented the concept of composite objects. As it has already been mentioned, it is recommended to use objects of arbitrary classes. Properties of these objects return values that are then displayed in corresponding grid cells. However, sometimes a class object doesn't have the required property but only refers to another object that contains the required information. There are a lot of such examples – a book written by some author or a stock quoted at a certain market. In both cases book or stock objects refer to other objects. However, when these objects are displayed in the grid, it is better to display not just object characteristics but some information taken from referenced objects.
As shown in the example, the book object provides information of publication date and name and has a reference to the author. If we have a binding list with books of different authors, it would be more convenient to see the author’s name in the grid in addition to book name and publication date.
Without declarative binding this can be achieved by adding new fields to book class to return values received from Author object or by creating a new class combining
properties of both objects and intended only for displaying in the grid. However, it is not a good solution. On the one hand, the code becomes bulky and contains duplicate information.
On the other hand, the book object has properties that it should not have. Besides, changing author class signature may cause problems as changes might also impact the book object.
Declarative binding offered by Dapfor’s framework makes things different. Marking Book.Author field as a composite field makes the grid process it in a special way by combining
Book and Author object fields.
When a book is displayed, the grid calls Book.Author property but does not display the Author object in a cell. When a header contains a column with FirstName identifier, the grid first searches
Book object for this field and if it is not found, the grid searches the Author object. The business logic remains the same. There are different Author and Book objects, their fields are not
duplicated and author data can be accessed by calling book.Author.FirstName. However, the grid displays data of both objects. It is possible to use any data type instead of
Author (including data types with variable number of fields).
If the book and the author have properties with the same names (e.g. Name), Author.Name property can be marked with FieldAttribute attribute for the purpose of displaying.
Copy | |
---|---|
class Author { public Author(string name) { Books = new List<Book>(); Name = name; } public IList<Book> Books { get; private set; } public string Name { get; private set; } } class Book { public Book(Author author, string name) { Author = author; Title = name; } public Author Author { get; private set; } public string Title { get; private set; } } |
Copy | |
---|---|
private void OnGridControl_Initialized(object sender, EventArgs e) { IList<Book> books = new List<Book>(); Author author = new Author("Agata Kristi"); books.Add(new Book(author, "Second front")); books.Add(new Book(author, "Detective story")); author = new Author("Conan Doyle"); books.Add(new Book(author, "The Blanched Soldier")); books.Add(new Book(author, "The Mazarin Stone")); grid.ItemsSource = books; } |
Copy | |
---|---|
class Book { ... [CompositeField] public Author Author { get; private set; } ... } |
Copy | |
---|---|
class Author { ... [Field("AuthorName")] public string Name { get; private set; } } |