Category Archives: .Net

Thinking with MVVM: Data Templates + ContentControl

I’m still playing with MVVM at work and I got a new occasion to setup a dialog using the MVVM methodology.

I really love the process of creating User Interface using MVVM, the process is so much natural ! Basically, I needed to create a “setup” dialog in the application I’m currently working on. I wanted to achieve something like this:

setup-dialog

Of course, I wanted to create this dialog using the power of WPF. My primary objective when I create a new dialog is to keep the code-behind empty. Using MVVM it took me about 10 minutes to create the basic structure of the dialog withouth writting a single line of code in the xaml.cs files.

Here is the process I followed to create this dialog. This is the “thinking with MVVM” part because I’m explaining the reasoning I had 🙂 You can download the source code for this example here.

Setup the main dialog

When I need quick prototypes, I often don’t use Blend and type the XAML directly into Visual Studio editor. That was the very first part I did to write this XAML:

  
        
            
            
        

        

        
            
        
    

Pretty easy isn’t it. Please note the “Content goes here” comment. I knew I wanted to put the settings dialogs here, but I didn’t know how… I named this file ConfigurationDialog.xaml.

Create sub-configuration dialogs

For this example, I created 2 sub-configuration dialogs just for the demo. I just put a TextBlock into a Grid to demonstrate the principles. Of course, we should add real configuration controls such as CheckBox, TextBox, etc. Those 2 new files are GeneralSettingsView and AdvancedSettingsView and are UserControls.

Create a ViewModel class for each View

I used to use an abstract base class for all my ViewModel classes where I implement the INofityPropertyChanged interface. I also use a trick from Josh Smith to throw an exception if the property name doesn’t exist when the PropertyChanged event is raised.

That gives us 3 new files: ConfigurationDialogViewModel, GeneralSettingsViewModel and AdvancedSettingsViewModel. Because I wanted configuration dialogs to have a common Name property (to identify them in the UI), I created a base class SettingsViewModelBase.

Setup the ViewModel of the main View

I needed the main View to expose the other configuration views available. I used an ObservableCollection for that:

public class ConfigurationDialogViewModel : ViewModelBase
{
        private readonly ObservableCollection settings;

        public ObservableCollection Settings
        {
            get { return this.settings; }
        }

        public ConfigurationDialogViewModel()
        {
            this.settings = new ObservableCollection();

            this.settings.Add(new GeneralSettingsViewModel());
            this.settings.Add(new AdvancedSettingsViewModel());
        }
}

Setup the main View  to consume datas from its ViewModel

I did some changes in the XAML to databind the ListBox’s ItemsSource property to the ViewModel. Because I always set the DataContext property of a view to its associated ViewModel, there is no ambiguity:

ItemsSource="{Binding Settings}".

The ListBox control has no idea how a SettingsViewModelBase object (that is in the associated ObservableCollection) should be displayed. We need a simple DataTemplate to specify this information:

            
                
                    
                
            

And finish using my favourite part !

We just setup a ListBox to consume a collection of SettingsViewModelBase class to build a menu, fine. By using a very simple DataTemplate, we said: “I want to render the SettingsViewModelBase object in the ListBox using a TextBlock”.

We can take this reasoning one step further. We have a View associated to each SettingsViewModelBase. ListBox was fine to have a collection of controls. How could we display only one control ?

We can use a ContentControl of course ! Because we want do display the dialog that is currently selected in the menu, we can use a simple DataBinding (here, the ListBox has been named ListBoxMenu):


One more time, we got a rendering problem. The ContentControl doens’t know how to render a SettingsViewModelBase object. Well, it’s not a big deal, just specify it:

    
        
            
        
            
        
    

What I’m saying here is that GeneralSettingsViewModel should be rendered using a GeneralSettingsView. That’s exactly what we need ! Because the Views are created using a DataTemplate, we do not need to setup the DataContext, it will be automatically registered to the templated object, the ViewModel.

Conclusion

The example I describe here is very simple. The goal was to show the process of creating a dialog thinking in the “MVVM” way. It was very natural to use the concepts I explain here. The code-behinds are completely empty and ViewModel classes are testable ! Because the View are XAML only, I can give them to a designer that will tweak them to make them have a nice look.

You can download the source code for this example here.

Using extension methods to raise an event

While reviewing some code at work the last days, I noticed I had a lot of similar methods I used to raise events. Basically, I did a test to check if the EventHandler is not null, and in this case, I raise the event:

// declaration of the event
public event EventHandler Saved;

// method I use to raise the event
private void OnSaved()
{
  if (this.Saved != null)
    this.Saved(this, EventArgs.Empty);
}

In some of my classes, I had around 10 methods like this one to do the check, and raise the event if the associated event handler is not null. I was thinking about creating an extension method that would do this job for me… And actually, it’s very simple ! Here is the code:

 /// 
/// Raise an event with a given EventArgs
/// 
/// EventHandler to raised
/// Sender of the event
/// Argument of the event
public static void Raise(this EventHandler handler, object sender, EventArgs e)
{
    if (handler != null)
    {
        handler(sender, e);
    }
}

Now, I can remove all methods that looks like the first I mentioned in the post, and simply write

Saved.Raise(this, EventArgs.Empty);

I also created an overload of the extension method that does not supply an EventArgs (in case you want to use EventArgs.Empty) and also a generic version (in case you want to use an EventHandler).
You can download the associated class here.

Why do I love Extension Methods in System.Linq ?

Because it helps me to write compact and clean code of course !

For example, I need to expose a property that gives the number of visible items in my ViewModel.

Old way:

        public int VisibleItemsCount
        {
            get
            {
                int i = 0;
                foreach (var item in this.Items)
                {
                    if (item.IsVisible)
                        i++;
                }
                return i;
            }
        }

Linq way:

public int VisibleItemsCount
{
    get
    {
        return this.Items.Count(item => item.IsVisible);
    }
}

Which one do you prefer ?