We’ll begin by creating a new WPF project in Visual Studio.
1. In Visual Studio, choose File | New | Project.
2. Select the WPF Application template and click OK.
Next, add an Entity Data Model based on the Northwind database. This model will provide the data for the entire application:
1. In the Solution Explorer, right-click the project name and select Add | New Item.
2. In the Data category, select the ADO.NET Data Model item and then click Add.
3. Select Generatefrom database and click Next.
4. Create a connection string pointing to the Northwind SQL Server database and click Next. In this example, you will use "NORTHWND.mdf", which should be installed in the Samples\Data folder.
5. Select the Tables node and click Finish.
Now build the project so the new Entity Data Model classes are generated and become available throughout the project.
Next, add a C1DataSource component to the application and connect it to the Entity Data Model:
1. Drag a C1DataSource component from the Toolbox onto the window. This is a non-visual component, so it can be placed anywhere within the window's inner content.
2. Select the new component and choose View | Properties Window.
3. In the Properties window, set the ObjectContextType property to the type of object context you want to use. In this case, there should be only one option in the drop-down list, something similar to "AppName.NORTHWINDEntities".
At this point, the C1DataSource has created an application-wide object (an EntityDataCache) that represents the Northwind database and has application scope. Additional C1DataSource objects on other forms will share that same object. As long as they are part of the same application, all C1DataSource objects share the same ObjectContext.
This unified object context is one of the main advantages SEF provides. Without it, you would have to create multiple object contexts throughout the application, and each would have to be synchronized with the others and with the underlying database separately. This would be a non-trivial task, and any errors could compromise the integrity of the data. The unified object context handles that for you transparently. It efficiently caches data and makes it available to all views in a safe, consistent way.
Now that our C1DataSource has an ObjectContext to work with, we will go on to specify the entity sets it will expose to the application through its ViewSources collection. Note that if you are familiar with ADO.NET, you can think of the C1DataSource as a DataSet and the ViewSources collection as DataView objects.
In the properties of the C1DataSource, locate the ViewSourcesCollection property and open its editor dialog. Click Add and then select Products from the EntitySetName drop-down list.
For this simple example, Products is all that is really necessary, but we could continue to create ViewSources within this C1DataSource in exactly the same way. We might, for example, create a ViewSource based on the Categories entity set allowing us to have a form that would be used to show the master-detail relationship between Categories and their Products. Conversely, there is no need to define all of the ViewSources that you might need in one single C1DataSource. You could have a separate C1DataSource for each ViewSource that you need. All you need to do is ensure that the C1DataSource components that you use utilize the same ObjectContextType.
In reality we’ll only want to bring a small subsection of the data contained within our database back to the client at any one time. This avoids overloading the client and network and also ensures that we are only presenting data that is relevant to the task our end user is engaged in. The traditional approach to this has been to create code (typically SQL queries) that we would run against the database to achieve our desired results. With C1DataSource, we can make use of the designer surface to achieve our goal without the need to write code by specifying server-side filters as property settings.
From the ViewSourceCollection editor, open the FilterDescriptor collection editor, add a filter descriptor and type the property name and a value for it for server-side filtering. If you need to filter more than one property, you can add additional filter descriptors.
Using exactly the same methodology, you can add SortDescriptors and GroupDescriptors to provide sorting and grouping on the data you retrieve.
With our C1DataSource configured, add a grid control to the form. This can be DataGridView, a C1FlexGrid or indeed any grid that you are familiar with. Set the grid’s DataSource property to the name of the C1DataSource (if you haven’t specifically named the C1DataSource, then this will be c1DataSource1) and its DataMember property to Products. The DataMember property will, in fact, display a drop-down list of all the ViewSources (or Entity Sets) that we defined for the C1DataSource.
When you select the C1DataSource control as the source of the binding, the binding designer shows you under the Path node the list of available entity sets (view sources) to choose from. In this case there is only one, Products.
Or you can just type the data binding in XAML:
ItemsSource="{Binding ElementName=c1DataSource1, Path=Products}"
At this point, the grid will automatically generate columns for all the fields in the Product type, and most grids will allow you to further customize these columns and their layout via their built-in designers.
If you use the standard Microsoft WPF DataGrid, be aware that its AutoGenerateColumns property defaults to False, so you must either generate columns at design time, or set AutoGenerateColumns to True in XAML.
Once you are happy with the grid's layout, save, build, and run the application. Notice that the data loads automatically, and you can sort and modify data as you would expect. All this has been achieved by adding just two items to your form (a C1DatSource and a data grid) and setting a few properties. You did not have to write a single line of code!
You could continue to add more controls to this form and bind them to specific items in the Products collection. To illustrate this point, add a TextBox control to the form. From the Properties window, expand the DataBindings section and bind its Text property to the ProductName, as illustrated.
or directly in XAML:
Text="{Binding ElementName=c1DataSource1, Path=Products/ProductName}"
Save, build and run the application again, and this time notice how the name of the product currently selected in the grid appears in the TextBox that you have just added to the form. If you then edit the product name in either control, the change will be immediately reflected in the other.