What is this “DataContext” you speak of?

July 14, 2012

I frequently see new WPF users confused about what the DataContext is, and how it is used. Hopefully, this can help clarify what the DataContext is, and how it is used.

What is the DataContext?

In WPF, there are two layers to an application: the UI layer and the Data layer.

The Data layer for an application starts out as null, and you can set it using the DataContext property. All UI objects will inherit their DataContext from their parent unless you specify otherwise.

When using the Model-View-ViewModel (MVVM) Design Pattern, the DataContext (Data Layer) is your application, while UI objects, like Buttons, Labels, DataGrids, and even Windows, are all just user-friendly items that allow a user to easily interact with the DataContext, which is your actual application and is typically comprised of ViewModels and Models.

How is it used

Whenever you do a basic binding in WPF, you are binding to the DataContext.

For example, when you write

<Label Name="myLabel" Content="{Binding Path=Name}" />

you are binding to myLabel.DataContext.Name, and not to myLabel.Name.

Other binding properties, such as ElementName or RelativeSource, can be used to tell the binding to lookup the property in something other than the current DataContext.

An Example

Lets start with a regular Window. Without setting the DataContext, the window still displays but there is no data behind it.

<Window x:Name="MyWindow" ...>
   ...
</Window>

Now suppose we set the DataContext to an object of type ClassA in the code-behind when this Window initializes:

public partial class MyWindow: Window
{
    public MyWindow()
    {
       InitializeComponent();
       this.DataContext = new ClassA();
    }
}

Now the data layer behind that the Window is an object of type ClassA.

If ClassA has a property called Name, I could add a Label to the window and bind it to Name property of the DataContext, and whatever value is stored in ClassA.Name would get displayed.

<Window x:Name="MyWindow" ...>
   <Label Content="{Binding Name}" />
</Window>

Now, suppose ClassA has a property called ClassB, and both classes have a property called Name. Here is a block of XAML which illustrates how the DataContext works. It also includes an example of how a control would refer to a property not in its own DataContext.

<!-- DataContext set to ClassA in initialization code -->
<Window x:Name="MyWindow"> 

    <!-- DataContext here is not specified, so it's inherited 
         from its parent's DataContext, which is ClassA -->
    <StackPanel> 

        <!-- DataContext inherited from parent, which is 
             ClassA, so this will display ClassA.Name -->
        <Label Content="{Binding Name}" />

         <!-- DataContext is still ClassA, however we are 
              setting it to ClassA.ClassB with a binding -->
        <StackPanel DataContext="{Binding ClassB}">

            <!-- DataContext inherited from parent, which is 
                 ClassB, so this will display ClassB.Name -->
            <Label Content="{Binding Name}" />

            <!-- DataContext is still ClassB, but we are 
                 binding to the Window's DataContext.Name, 
                 which is ClassA.Name -->
            <Label Content="{Binding 
                       ElementName=MyWindow, 
                       Path=DataContext.Name}" /> 
        </StackPanel>

        <!-- We've left the StackPanel with its DataContext 
             bound to ClassB, so this Label's DataContext 
             is ClassA (inherited from parent StackPanel), 
             and we are binding to ClassA.ClassB.Name -->
        <Label Content="{Binding ClassB.Name}" />
    </StackPanel>
</Window>

As you can see, all the basic bindings look for their value in the data layer (DataContext) of the UI object

Summary

So to summarize, WPF applications have two layers: the UI layer and the Data layer. The data layer for an application starts out as null, and can be set using the DataContext property. UI objects without a DataContext set will inherit their data layer from their parent object. Bindings are used to look up values in the data layer, and display them in the UI layer.

When using the MVVM design pattern, the data layer is your application, while the UI layer just provides a user-friendly way to access the Data layer.


ComboBox’s SelectedItem not Displaying

August 20, 2011

I see a lot of posts on StackOverflow about WPF ComboBoxes not displaying the SelectedItem correctly.

The code given usually looks something like this:

<ComboBox ItemsSource="{Binding MyList}"
          SelectedItem="{Binding MyItem}" />

The problem is simple: By default WPF compares SelectedItem to each item in the ItemsSource by reference, meaning that unless the SelectedItem points to the same item in memory as the ItemsSource item, it will decide that the item doesn’t exist in the ItemsSource and so no item gets selected.

To work around this, you can either use the ComboBox’s SelectedValue and SelectedValuePath to set the SelectedItem by Value instead of by Item

<ComboBox ItemsSource="{Binding MyList}"
          SelectedValuePath="Id"
          SelectedValue="{Binding SelectedId}" />

Or you can overwrite the .Equals() method of the MyItem class so that it returns true if two item’s have the same data, not just the same memory reference.

public override bool Equals(object obj) 
{ 
    if (obj == null || !(obj is MyClass)) 
        return false; 
 
    return ((MyClass)obj).Id == this.Id); 
}

Definition of a DependencyProperty

July 17, 2011

I was recently asked what a DependencyProperty was and how it was different than a regular Property. The MSDN definition says the DependencyProperty class “represents a property that can be set through methods such as, styling, data binding, animation, and inheritance”, but that doesn’t really tell you what a DependencyProperty is, and why it is such an important part of WPF.

The real reason DependencyProperties are so special, is they are not meant to contain a value. Instead they are meant to contain a pointer, or address, of another value.

Instead of saying “This TextBox’s text is going to be Foo”, you end up saying “This TextBox’s text points to a string over here which currently contains Foo”.

The power in this is that it allows you to manipulate the source value without knowing about or altering the UI. If PropertyChange notification is setup, the UI will automatically display a new value without anyone ever touching it.

For example, suppose you had an online shopping application. The User’s Name is displayed in the welcome message, in the top right corner by the My Account link, and on the bottom in the Suggestions for <UserName> section. If the current user changes, you simply have to change a single property to the new value, and anywhere that displays the UserName will be updated automatically. You don’t need to remember which UI fields need to be updated or to change them all manually in the code.

So my definition of a DependencyProperty is a property that depends on another for its value.