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.


Approaching another programmer about code-quality

July 2, 2012

This is another post I wrote for the Programmers.SE Blog a few months back. They’ve finally published the article, so I thought I’d include a copy of it on my own blog.


Programmers have to work with large amounts of bad code. Sometimes its your own code, but other times its another programmer’s code. If you have to frequently work with another programmer’s bad code, you will eventually wish to approach them about their code quality, however how to do this without causing offense or resentment is not always easy. This article is about the approach I would take when wanting to casually talk with another programmer about their code quality.

Determine the problem

First off, determine what exactly the problem is, and verify that it is worth bringing up. Ask yourself:

  • Do you work with this person on a regular basis?
  • Will you be working with, and maintaining their code in the future?
  • Is this an actual problem that harms productivity, performance, or security, or is it simply a case that your preferences are different from theirs? For example, simply complaining that “your naming convention doesn’t match mine” is not a very good reason, however saying “your naming convention makes it hard to understand what is going on in the code” is a much better.

If you answered yes to all of those, then it sounds like you might have a good reason to approach someone about their code quality.

Gather your arguments

Once you’ve determined there is a valid reason for trying to change the way another programmer does things, get your arguments prepared. Identify why the code is harmful to the development environment, and figure out the ideal way of coding it instead. Pick some code samples illustrating the problem, and write your own way of coding the same piece. Determine what your arguments are for why your code is better than the existing code sample. Don’t use arguments such as “it’s best practice”, but instead explain why it’s a best practice (readability, maintainability, reusability, etc)

Approaching the other programmer

Now that you know your arguments for why you think your code is better than theirs, and have a clear idea of what the ideal code should look like, arrange a time to talk with the other programmer.

This could be a casual conversation, or it could be setting up an appointment to talk with them about your concerns. How you choose to approach your co-worker is based on your level of comfort with them, the organization’s environment, and both of your ranks within the organization. For example, if I wanted to talk to the programmer next to me, I might simply ask them if I could have a moment of time whenever they’re available to talk with me about a piece of code, however if it’s my boss, I might send him/her an email asking if I could setup a brief meeting with them to discuss some code I’ve been working on.

Some people might argue that approaching a boss is different than approaching a co-worker, however I feel they are both people and both deserve equal respect. The only real difference I see is that your boss’s time is usually more valuable to the company, so be aware of that when talking with him/her.

What to say

When you actually talk with the other programmer, I usually find a good way to start the conversation is to ask them to explain their code. Ask if there was a reason for their style of coding, or tell them you’ve never seen something coded that way, and ask them why they chose that method. Really listen to what they have to say during their explanation. It could be that their way is right, and you are wrong, in which case take notes and learn from it!

If you still think the code is bad and worth changing, show the other programmer how you would code the same piece of code, and tell them why you would code it that way over his/her way (better performance, fewer chances of errors, easier for other programmers to read/maintain, etc).

Focus on why your method of coding is better, and not why their method is worse. Nobody likes being accused of writing bad code, although in reality we were all new once and I’m sure we’ve all written some horrendous code at some point in our lifetime. Be sure to keep the conversation focused on the code, and avoid turning it personal by talking about the person who wrote the code. It is always best if you can show that you understand that sometimes bad code gets written, whether it was due to time constraints, inexperience, or simply a bad day.

In addition, don’t try and get them to change their old code (unless you are their boss and want them to spend time doing so). Your goal is to educate them so they stop making the same mistake in the future, not berate them over past mistakes and punish them by extra work.

Afterwards, see if he/she still supports their coding style over yours. If they are open to improvement, they will likely change their way of coding going forwards. But if they still prefer to use their coding style, you are not likely to change their opinion, so drop the subject and don’t bring it up again unless their code is actually harmful.

Conclusion

Remember, nobody can write perfect code, and good programmers are always looking for improvement. The world of programming is so big that its impossible to know everything. It’s very likely that the other programmer doesn’t know there is a problem with their code, and would appreciate the input, providing you do it in such a way that you are teaching them, and not insulting them.

So don’t be afraid to approach another programmer about their code quality. I know I would appreciate the conversation, and I think you would too.