DataSource for Entity Framework in WPF
DataSource for Entity Framework in WPF / Customizing View
In This Topic
    Customizing View
    In This Topic

    In many situations, you may want to use custom views that do not correspond directly to the tables and views provided by the database. LINQ is the perfect tool for these situations allowing you to transform raw data using your language of choice using query statements that are flexible, concise, and efficient. Entity Framework DataSource (EF DataSource) makes LINQ even more powerful by making LINQ query statements live. That’s why its LINQ implementation is called LiveLinq. We will show the power of LiveLinq in Live Views|document=WordDocuments\C1DataStudio-WPF.docx;topic=Live Views. For now, suffice it to say that you can transform your view to shape it whatever way you want using LINQ operators without losing full updatability and bindability.

    Let’s try, for example, one of the LINQ operators: Select (also called projection), to customize the fields (properties) of our view.

    To customize a view, follow these steps:

    1. Using the project we created to demonstrate Large Datasets: Paging|document=WordDocuments\C1DataStudio-WPF.docx;topic=Large Datasets\: Paging, add a new form with a C1DataSource component using the same ObjectContextType as before. Note that you can make this the startup form to save time when you run the project.
    2. Create a ViewSource in the ViewSourceCollection editor. Use the Products table in our sample database.
    3. Add a grid to the window designer and, as before, set its AutoGenerateColumns property to True. But this time we won’t bind the grid to C1DataSource in XAML. Instead, we will bind it in code, because we will create a custom view in code.
    4. Create a custom live view and bind the grid to that view with the following code:
    Visual Basic
    Copy Code
    dataGrid1.ItemsSource = _
        (From p In c1DataSource1("Products").AsLive(Of Product)()
          Select New With
          {
               p.ProductID,
               p.ProductName,
               p.CategoryID,
               p.Category.CategoryName,
               p.SupplierID,
               .Supplier = p.Supplier.CompanyName,
               p.UnitPrice,
               p.QuantityPerUnit,
               p.UnitsInStock,
               p.UnitsOnOrder
           }).AsDynamic()
    

     

    C#
    Copy Code
    dataGrid1.ItemsSource =
        (from p in c1DataSource1["Products"].AsLive<Product>()
         select new
         {
             p.ProductID,
             p.ProductName,
             p.CategoryID,
             CategoryName = p.Category.CategoryName,
             p.SupplierID,
             Supplier = p.Supplier.CompanyName,
             p.UnitPrice,
             p.QuantityPerUnit,
             p.UnitsInStock,
             p.UnitsOnOrder
         }).AsDynamic();
    

     

    Here c1DataSource1["Products"] is a ClientCollectionView object. It is the view that is created by the view source that we set up in the designer (if you need to access the view source itself in code, it is also available, as c1DataSource.ViewSources["Products"]). The AsLiveT_Method method call is needed to specify the item type of the view (Product) so LiveLinq operators can be applied to it. The result, c1DataSource1["Products"].AsLive<Product>(), is a View<Product>. The C1.LiveLinq.LiveViews.View is the main class of LiveLinq, used for client-side live views. LINQ operators applied to live views preserve their updatability and bindability. They are the same usual LINQ operators, but the fact that they are applied to a live view gives them these additional features that are critically important for data binding applications.

    Note: AsDynamic() must be applied to this view because its result selector (the select new… code) uses an anonymous class. This is a minor LiveLinq limitation, only for anonymous classes. If you forget to add AsDynamic() to such view, you will be reminded by an exception.
    1. Save, build and run the application.

    The grid now shows the columns we defined in the ‘select’ clause of our LiveLinq view. Note also that all columns are modifiable. It may not seem like a big deal; however, it is an important feature that would be difficult to implement on your own for this customized view, especially when adding and deleting rows, which, as you can see here, is also supported. To try deleting a row, just select a row and press the Delete key. To try adding a row, you’ll need to add a button to the window executing the following code:

    Visual Basic
    Copy Code
    Dim newItem = CType(dataGrid1.ItemsSource, System.ComponentModel.IEditableCollectionView).AddNew()
         dataGrid1.ScrollIntoView(dataGrid1.Rows.Count - 1, 0)
    

    C#
    Copy Code
    object newItem =
       ((System.ComponentModel.IEditableCollectionView)dataGrid1.ItemsSource).AddNew();
    dataGrid1.ScrollIntoView(newItem);
    

     

    This is needed only because Microsoft WPF DataGrid does not provide a built-in interface for adding new rows.

    Bindability is achieved because the views are always ‘live’; they aren’t simple snapshots of static data. To prove the point, construct an exact replica of the form that we’ve just built. At this stage, you might find it easier to add a menu to your application to make accessing the forms you’ve created easier. Save, build and run the application.  This time, open two instances of the form you just created and change some data in the grid on one of the forms. Notice how the corresponding data in the grid on the other form is changed automatically. Remember, you have not had to write a single line of code for the grids in these forms to synchronize the changes that you’ve just made.

    You will see more of what LiveLinq can do in the Live Views|document=WordDocuments\C1DataStudio-WPF.docx;topic=Live Views topic.