Friday, February 21, 2014

Binding Source Objects in WPF

Recently I received a request from one of the followers on ways to bind source objects. So, I thought it would be a nice topic for a post. Hence, it's here.

For a binding to work, there should be a source object. The selection of source object is totally dependent on the way binding is used. If no binding source is provided, then bydefault DataContext of an element is used. The most common way is to set DataContext on parent element and let it flow to all its children. But apart from this, there are 3 other ways by which one can point to source object: 

1) RelativeSource - Relative source is one of the property on a binding that can point to relative source markup extension which tells where the source can be found in hierarchy. In simple words, it is the relative path in the element hierarchy.

2) ElementName- Another way of specifying source is by using ElementName in which other element present in the current UI can be used as a source object. Here the source object has to be part of Visual tree.

3) Source - Another way is by using Source property on a binding. This source property has to point to some object reference and the only better way to get object reference down into the source property is that uses static resource which points to some object in a resource collection. 

Now let's quickly jump on to the code of each one of these. To make my example simple, I am taking only two fields named Employee Id and Employee Name and will display it in a WPF DataGrid.

As a ground work, I created a file to handle my data access part called DAL.cs. My all the business entities are kept in class called Employee and are populated in DAL class. Below is the snapshot of both my classes:

And below is my XAML skeleton to display the data in the DataGrid:

You might notice that by this time, I haven’t set the DataContext and ItemsSource property for my DataGrid. So, if you will run this application, your DataGrid will be empty with zero tupples. Going forward, I’ll pick each one of the binding sources to populate out DataGrid.
Let’s take Relative binding as the first one.

Using RelativeSource:
The common practice for setting DataContext in code-behind is by using the this keyword. What if, anyone don’t want to set this in code-behind by using this keyword. Well, the answer here is RelativeSource as shown below:

Setting the RelativeSource to Self is equivalent to this. So, one need not to set DataContext in code-behind.

Using Source:
Here we will see binding Source property on a binding. Let’s say I want to set ItemsSource as Employees and don’t want to rely on the DataContext been set to something that expose to Employees collection. In that case, I can point explicitly to some Source object that contains my collection. And the typical way of doing this is by using Resources on the current view and further set that resource key as ItemsSource. Code will be:

And you will see the output as:

Using ElementName:
To demonstrate this property, I am going to modify above sample a bit by adding a Delete button. This delete button will delete the selected row. To achieve this, I hooked a button and respective command as shown below:

Please note, here DataContext of the button is coming from the parent which is Window itself. Here we are using CommandParameter because we need to send selected row as a parameter to our command. Point to note here is, we need to set ElementName property with our DataGrid because our selected employee will be part of DataGrid and the Path property with SelectedItem.

If everything is in place, you are ready to go. Hope you enjoyed learning!!!

No comments:

Post a Comment