DataContext, Data Templates and Data Template Selectors

I spent some time today working on DataTemplateSelectors. I’d never used them before, but it made me think about all the different ways there are to set the DataContext in WPF. After talking through this with a friend, I realized that maybe some of these minor nuances aren’t very clear. I figured if I write about it, at least I can reference it again later when I forget.

OK, my first assumption here is that you’re being a good programmer and using MVVM, this is WPF after all.

Binding To Code-Behind

This is the most basic kind of binding. When you first learn MVVM, this is probably going to be your first step. Binding to code-behind just requires you to set your DataContext to the xaml.cs file attached to your View –

<Window .....
        DataContext="{Binding RelativeSource={RelativeSource Self}}">           
</Window>

In the long run I don’t recommend this one, you’re always going to want to bind a View to a ViewModel in a separate class. It just makes it so much cleaner. This leads to my next header

Binding To ViewModel

This one is really similar to binding to your code behind. The only difference here is that instead of binding to yourself, you’re binding to your View Model. Simple right, OK, here’s the code –

<Window x:Class="MyProgram.MainWindow"
        xmlns:local="clr-namespace:MyProgram"
        mc:Ignorable="d">

    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
</Window>

Make sure to get the correct namespace (in this case local) of your View Model. When using this style of datacontext setting, you’re going to have to do this for each and every View. At first this might seem OK, but the further into this you get, the more cumbersome this method becomes.

OK, onto the next method; DataTemplates!

Binding Using DataTemplates

DataTemplates are used all over WPF (seriously, you should take a look into how awesome data templating is in ListViews if you don’t believe me). When it comes to Views and View Models the data template allows you to load your Views by specifying the View Model you want. Instead of loading View first, you can call the View Model (along with it’s constructor) and the ContentPresenter will figure out what View to serve up alongside it.

The beauty of this is you can now pass around data between your view models, making it easier to structure your program.

You still need to set the DataContext of your initial entry point View. In the case above it’s the MainWindow and MainWindowViewModel. So, even in this method, make sure to set the DataContext first.

Now, add some kind of presenter (it can be a ContentPresenter, ContentControl or UserControl). This will be the View Controller that will change out the different views according to your bindings. Here’s the code for the View –

<Window x:Class="MyProgram.MainWindow"
        xmlns:local="clr-namespace:MyProgram"
        mc:Ignorable="d">

    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>

    <Grid>
        <ContentPresenter Content="{Binding View}" />
    </Grid>
</Window>

Here’s the code for your View Model (I’m not including the INotifyPropertyChanged interface, I’m assuming you’ve got that figured out by now, but if you’re looking for a framework, try JustMVVM). MVVMBase is just a base class that all View Models must inherit from.

class MainWindowViewModel : MVVMBase
{
    private MVVMBase _currentViewModel;
    public MVVMBase CurrentViewModel
    {
        get { return _currentViewModel; }
        set
        {
                _currentViewModel = value;
                OnPropertyChanged();
        }
    }

    public MainWindowViewModel()
    {
        // Setting View to Home screen
        CurrentViewModel = new HomeViewModel();
    }
}

For the application to figure out what view to load for the ContentPresenter, we need to add a Data Template. The simplest place to put this is in App.xaml, then it’ll work throughout the entire application, but in reality you can put this in any Resources section

Below are 3 different data templates for 3 different views.

<Application x:Class="MyProgram.App"
             xmlns:view="clr-namespace:MyProgram.View"
             xmlns:viewmodel="clr-namespace:MyProgram.ViewModel"
             Startup="Application_Startup"
             StartupUri="MainWindow.xaml">

    <Application.Resources>

        <DataTemplate DataType="{x:Type viewmodel:HomeViewModel}">
            <view:Home />
        </DataTemplate>

        <DataTemplate DataType="{x:Type viewmodel:SettingsViewModel}">
            <view:Settings />
        </DataTemplate>

        <DataTemplate DataType="{x:Type viewmodel:HelpViewModel}">
            <view:Help />
        </DataTemplate>

    </Application.Resources>
</Application>

For most of my applications that I’ve worked on, this has worked out great. I have a single spot where I put all my data templates and then I’m in complete control over what views are being loaded. There are occasional situations that require an even more complicated solution, so here we go, my final option, the DataTemplateSelector.

Data Template Selector

In theory this is another alternative to using Data Templates, but it gives a little more control over the issue. Sometimes a need arises where you have multiple Views for a single View Model, or you’ve created a generic form of ViewModel<T> but you can’t define a DataTemplate for generics in XAML. In this case, you can create a Data Template Selector, which allows you to select the associated View template in code.

Here’s some example code of the Selector –

public class CustomDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate HomeTemplate { get; set; }
    public DataTemplate SettingsTemplate { get; set; }
    public DataTemplate HelpTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == null)
            return base.SelectTemplate(item, container);

        var viewModel = item as PropertyChangedBase;
        var viewModelType = viewModel.GetType();

        if (viewModelType.IsGenericType && viewModelType.GetGenericTypeDefinition() == typeof(HomeViewModel<>))
                return HomeTemplate;

        else if (viewModelType == typeof(SettingsViewModel))
            return SettingsTemplate;

        else if (viewModelType == typeof(HelpViewModel))
            return HelpTemplate;

        else
            return base.SelectTemplate(item, container);
    }
}

Let’s unpack this a little bit. The properties at the top can be set in the XAML to the data templates we created in the previous section (see below for how it’s done). The first part of the if statement shows how you can handle a generic type for a template selector. This means that any HomeViewModel<T> will load the HomeTemplate.

The reason I ended up using this over Data Templates is for the else part at the end. I was creating a library that was to be consumed by others. I wanted to be very specific about what templates were loaded in my library, but also leave open the possibility of other people adding their own templates. I guess I could have created some extensible class that allows people to add more templates, but by calling the base implementation of the DataTemplateSelector

return base.SelectTemplate(item, container);

I don’t have to do anything special, I just let the normal DataTemplates take over again like usual.

Here’s how this Selector was implemented in XAML –

<Grid>
    <Grid.Resources>

        <DataTemplate x:Name="HomeTemplate" >
            <view:Home />
        </DataTemplate>

        <DataTemplate x:Name="SettingsTemplate" >
            <view:Settings />
        </DataTemplate>

        <DataTemplate x:Name="HelpTemplate" >
            <view:Help />
        </DataTemplate>

        <viewmodel:CustomDataTemplateSelector x:Key="ViewTemplateSelector"
                                              HomeTemplate="{StaticResource dialogException}"
                                              SettingsTemplate="{StaticResource dialogOKCancel}"
                                              HelpTemplate="{StaticResource dialogOK}" />

    </Grid.Resources>

    <!--  Dialog User Control  -->
    <ContentPresenter Content="{Binding View}"
                      ContentTemplateSelector="{StaticResource ViewTemplateSelector}" />
</Grid>

And like I said, any other View / View Model templates can either be added to the Template Selector (if you have access to it) or can just be placed in App.xaml like usual.

Well, I think that’s all I’ve got about Data Templates. Hopefully by putting this all together in one place I’ve made somebody’s life easier. If you see anything wrong, let me know in the comments.

Visual studio snippets

I only recently graduated from part-time coder to full-time coder. My previous job was part engineer, part programmer, so I never really spent enough time looking into some of the nicer features of Visual Studio.

Luckily, that’s all changed now. Snippets have by far become my favorite coding shortcut. At first, I didn’t think I had much use for it. If I had to create a long chunk of code I’d just revisit an older project and copy it over, no problems right? Well, now that I’m always coding I see what a waste of time that was.

I’m sure you can find out how to do these just about anywhere, in fact, I’m certain MSDN has a nice section on it, but I’m going to run you through it all the same.

Here’s my favorite snippet, it’s for an IConverter to be used in your xaml. These always have exactly the same starting point, so they’re perfect.

Step one is create a new file with the extension .snippet. In this case, I named it IConverter.snippet.

Now copy all the following code into it and I’ll go through it step by step. I’ve highlighted all the sections you’ll want to change.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>**Converter**</Title>
      <Author>**YourName**</Author>
      <Description>
      </Description>
      <HelpUrl>
      </HelpUrl>
      <Shortcut>**SnippetShortcut**</Shortcut>
    </Header>
    <Snippet>
        <Declarations>
            <Literal>
                <ID>**type1**</ID>
                <Default>**double**</Default>
            </Literal>
            <Literal>
                <ID>**type2**</ID>
                <Default>**double**</Default>
            </Literal>
            <Literal>
                <ID>**class**/ID>
                <Default>**___Converter**</Default>
            </Literal>
        </Declarations>
        <Code Language="csharp"><![CDATA[**[ValueConversion(typeof($type1$), typeof($type2$))]
    public class $class$ : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is $type1$))
                return 0;


        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    **$end$]]>
            </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

OK, it’s pretty straightforward from here. Give the snippet a Name and Author, although they don’t really matter too much. More importantly, replace SnippetShortcut with something useful, in my case I used conv. This is the shortcut you’ll use in Visual Studio to run the snippet. All you need to do it type conv[TAB][TAB] and you’re up and running.

In the declarations section,

<Declarations>
    <Literal>
        <ID>**type1**</ID>
        <Default>**double**</Default>
    </Literal>
</Declarations>

You can declare all the variables in your code snippet, with an ID and Default Value. The ID can be used in the codeblock below. You have to surround the ID in $, like this $type1$ for the snipper to find and replace it correctly. The default value should be something sensible. I like to try and make that a useable value, so if I forget what that should be, the default gives me a hint.

Finally, replace the section that is highlighted bold (don’t delete the [CDATA[ or $end$ sections or it’ll break). Make sure to replace any section that might be a variable in your code block with the correct $variablename$.

OK, so you’re all done, now what? Well, open up Visual Studio, goto Tools —> Code Snippets Manager, click Add and locate your snippet folder. That’s it.

Now, after all that hard work you can relax and enjoy the beauty of code snippets.

Naming things is hard

There are only two hard things in Computer Science: cache invalidation and naming things.

— Phil Karlton

I thought this was a good way to get rolling on this blog. I’ve always been really bad at introducing myself (in real life too) so just go with it. If it helps, just picture someone standing up in a room full of people sweating profusely and mumbling while reading this.

Naming things is really hard. This isn’t just in relation to computer science either. My wife and I spent months picking out our kids names (I think we only decided on the 2nd kids name on his due date).

I spend (probably too much) time every day sitting in front of my computer trying to think of a good name for something. When I finally decide that it sounds good, I plow onwards until I reach my next naming problem. The really bad part is that you end up with a lot of code that looks like this –

UnitBuilder unitBuilder = new UnitBuilder();

The new name you come up with is so good, you end up using it for an instance and a class. I’m not going to throw away gold like that.

Naming this blog was hard too. I think it took me close to a week to even come up with one name. They were all terrible of course, I mean how do you name something that can be about anything to do with programming. I don’t know about you, but I think the best programming blog name has to be CodingHorror. My rejects included NeverendingCoding and StumblingThroughCode. I even tried this whole blogging thing once before and came up with the super clever name of EternallyRefactoring (I told my wife and she didn’t know what that meant, probably a red flag).

Somehow, I thought I’d found a good one that nobody else was using, CodeBlock.wordpress.com, but of course that was already taken, along with CodeBlog, AnotherCodeBlog and countless other “clever” ideas that I had. Anyway, here’s where I ended up. The idea for me is that you insert a breakpoint into your coding day to read my blog. Of course, if you’re a web dev you might be wondering what the hell a breakpoint is anyway.

Here’s a little about me. I’m a self-taught software developer. I didn’t get started until I was around 24, learning Java first and then moving into .NET with VB and C#. I’m now working full-time as a software developer in a small department of a large company, doing WPF and C# exclusively. I like to mess around with side projects in my spare time. I’ve developed a simple kids learning game for Android and iOS, and I have a couple of projects on GitHub that I’ve cobbled together when I find time.

This blog is probably going to be a stream of consciousness. Like I said, I tried this blogging thing once before and it didn’t really work out that well. I felt a lot of pressure to try and blog regularly and for all my blogs to be well researched. Not this time my friends. I’m going to be writing about things I’ve stumbled across at work or things I think people need to take a look at. That’s it. Very little research. If you’re looking for that, you’re in the wrong place bud.

Alright, thanks for stopping by!