- Posted by Diederik Krols on January 21, 2012
This article describes how to build custom WinRT Metro controls in C# and XAML, with the Developer Preview version of Visual Studio 11. WPF, Silverlight, and WinRT Metro have two ways to roll your own controls: custom controls, and user controls. User controls are composite controls that are created by dragging and dropping other controls onto a XAML surface. They are nothing more than content controls that are optimized for design-time use. User controls are typically for sharing within an application, but not with other applications. Custom controls on the other hand, are created by defining a class that derives -directly or indirectly- from Control, together with a definition of a default style. Custom controls are typically hosted in control libraries, and shared between multiple applications. Custom controls are much more flexible in terms of reuse, styling, templating, and theming.
For this article I created a simplified version of the Slider control. It's called SimpleSlider. It has a Minimum, Maximum, and Value property. Visually it only consists of a moving part -the thumb- and a colored rectangle of which the width is bound to the Value property:

I first created a project in .NET 4.0 WPF with Visual Studio 10. Then I tried to implement the same functionality in a .NET 4.5 Metro-style app. Here are screenshots of both versions:
Creation of the control
For WPF there is a WPF Custom Control Library project template. It creates a custom control derived from the most common base class: Control. You might want to change that into a more appropriate class, like ItemsControl or Selector. RangeBase would have been the ideal base class for a Slider, but I wanted to build everything from scratch, so I kept the default.
The Visual Studio template assigns the DefaultStyleKey dependency property through an OverrideMetaData call in a static constructor. It also creates a Themes folder with a generic.xaml with an (almost) empty default control template for the new user control. The project's assembly information gets a ThemeInfo attribute that contains the locations where that default style will be searched when the control needs to be displayed.
That's how it goes in Silverlight and WPF. For Metro style apps there is NO such project template - there's not even a class template for a custom control. The reason is that things like DefaultStyleKey, ThemeInfo and generic.xaml are not supported (yet?). So you have to create the SimpleSlider class and its generic.xaml manually. To inject the style file into the application, add it as a resource dictionary in app.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Adding Bindable Properties
By deriving from Control, a custom control inherits a set of useful dependency properties. These are properties to which the user of the control can databind: things like Background, FontSize, and Template. You can add custom dependency properties yourself - Visual Studio has a code snippet for that: propdp. It generates the dependency property registration for you:
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", "Object", typeof(SimpleSlider).FullName, new PropertyMetadata(0.0, OnValueChanged));
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
The PropertyMetadata allows you to define the default value and the method that should be called when the property's value is changed. When the Value property of the SimpleSlider is changed, we're going to redraw it:
private static void OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var customSlider = (SimpleSlider)dependencyObject;
customSlider.UpdateControls();
}
Contrary to WPF and Silverlight, the Register method takes strings instead of types. This is just temporary: Microsoft will regain compatibility with Silverlight and WPF in the upcoming beta of WinRT.
In the Developer Preview you need to specify 'Object' as the property type to make the bindings work, but that's also just a temporary bug.
Styling
Defining the default style for your custom control is not different from current technologies. You just define a style with the corresponding target type in a resource dictionary. Here's the full definition of the default style for the simple slider:
<Style TargetType="ctrl:SimpleSlider">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:SimpleSlider">
<Grid>
<Border Height="8"
VerticalAlignment="Stretch"
Background="LightGray" />
<Canvas Margin="0"
MinHeight="8">
<Rectangle x:Name="PART_Rectangle"
Height="8"
Fill="Yellow" />
<Thumb x:Name="PART_Thumb"
Width="8"
Height="8" />
</Canvas>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I would suggest to NOT use TemplateBinding in a style definition, since this doesn't seem to work yet. The following code, where I replaced the Border in the template by a Rectangle with its Width bound to the actual width of the control, does not work in the Developer Preview:
<Rectangle Height="8"
Width="{TemplateBinding ActualWidth}"
VerticalAlignment="Stretch"
Fill="LightGray" />
If you're looking for inspiration about styles: all the default styles for WPF and Silverlight controls are on MSDN. You can find the full style for the WPF Slider here. The WinRT Metro styles are not published yet, but if you open the Basic Controls Sample, you'll find a light_generic.xaml file that has all the information. You'll immediately see why my control is called 'Simple' Slider...
Templating
The user of your custom control should be able to decide for 200% on how your control should look like in his application. But of course he needs to respect some basic requirements: a slider will always have a moveable part (the Thumb) and an indication of its Value (the Rectangle). The required elements in a style are by convention named with a 'PART_' prefix. The code behind file also exposes these elements' name and type through a TemplatePart attribute:
[TemplatePart(Name = ThumbPartName, Type = typeof(Thumb))]
[TemplatePart(Name = RectanglePartName, Type = typeof(Rectangle))]
public class SimpleSlider : Control
{
private const string ThumbPartName = "PART_Thumb";
private const string RectanglePartName = "PART_Rectangle";
// ...
}
This indicates to potential control re-stylers that the code-behind relies on these parts. So if you override the default style, you should make sure that it contains elements with the expected name and type.
The style -default or custom- is typically applied in the OnApplyTemplateCore method, that's Metro's version of the OnApplyTemplate method that we know from Silverlight and WPF. As a developer of custom controls, you should wrap the template part manipulation in defensive code. After all, you never know what template you will be dealing with at run-time. Use GetTemplateChild to find the template part you're interested in, since WPF's Template.Find does not exist in Silverlight and Metro:
protected override void OnApplyTemplateCore()
{
base.OnApplyTemplateCore();
this.thumb = this.GetTemplateChild(ThumbPartName) as Thumb;
if (this.thumb != null)
{
this.thumb.DragDelta += this.Thumb_DragDelta;
}
// ...
}
All changes to a dependency property fire the INotifyPropertyChanged event. Unfortunately, in the Developer Preview something goes wrong in the central binding mechanism when the ElementName property is used. The following code displays the initial slider value correctly in a textblock. But when the thumb is moved, the textbox just disappears:
<TextBlock Text="{Binding Path=Value, ElementName=SimpleSlider}" />
If you bring a viewmodel in the equation and use it as datacontext for slider and textbox, then everything works as expected. This looks like overkill, but as a die-hard MVVM developer I can live with that. Here's the -working- code for the value binding of the pacman-shaped slider:
<TextBlock Text="{Binding SliderValue}" />
Overriding a style
To override the default style, you just need to provide a new one, e.g. through XAML:
<ctrl:SimpleSlider.Style>
<Style TargetType="ctrl:SimpleSlider">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:SimpleSlider">
<!-- Your template here -->
<!-- ... -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ctrl:SimpleSlider.Style>
Just make sure you use the required template parts.
Conclusion
There are a couple of glitches in the Developer Preview, but in general the WinRT Metro framework already has most of the foundations to build reusable custom control libraries. In a couple of weeks there will be a new release: not a true beta release, but a so-called 'consumer preview'. I can't wait to get my hands on it...
Code
Here's the full code, the WinRT version was built with the Visual Studio 11 Developer Preview:
WPF: U2UConsult.WPF.SimpleSlider.zip (24,81 kb)
WinRT: U2UConsult.WinRT.SimpleSlider.zip (34,84 kb)
Enjoy!
Afterthought
I realize that it was unfair to compare WinRT Metro directly to WPF. The WinRT Metro mechanisms are much closer to Silverlight than they are to WPF. WinRT Metro currently feels like a stripped-down version of Silverlight (which itself is a stripped-down version of WPF). At first, I found that a bit strange. After all, the WinRT runtime is not restrained by footprint size: it doesn't have to be smaller than the Flash plugin. It's also not constrained by browser and operating system compatibility: it doesn't have to run in Opera on a Windows Server 2000, nor in Safari on a Mac. On the other hand, WinRT is targeted to run on cheap (well, hopefully) tablets powered by ARM processors, the 32-bit cores that drive smartphones, MP3-players, and the Nintendo DS. That counts as a constraint.
- Posted by Diederik Krols on January 3, 2012
WinRT, the new Windows 8 runtime for Metro applications, introduces a new interface for collection change notification. IObservableVector<T> replaces ye olde INotifyCollectionChanged. The ObservableCollection class still exists, you can continue to use it. Unfortunately its collection change events are ignored by the WinRT framework. I can assure you that this will give cross-platform developers a serious headache - or worse. Don't say I didn't warn you:

The IObservableVector<T> interface is defined, but the framework does not contain an implementation yet. There's no built-in collection that raises the new VectorChanged events. The fresh cocoon framework on CodePlex contains an implementation of ObservableVector<T>. Unsurprisingly it's a light-weight wrapper around an IList<T>. The class is described here.
Here's my own version of the class - I just adapted it to my property change notification mechanism:
namespace Mvvm
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Data;
/// <summary>
/// IObservableVector<T> implementation.
/// </summary>
public class ObservableVector<T> : Collection<T>, INotifyPropertyChanged, IObservableVector<T>
{
// *** Events ***
public event PropertyChangedEventHandler PropertyChanged;
public event VectorChangedEventHandler<T> VectorChanged;
// *** Constructors ***
public ObservableVector()
: base()
{}
public ObservableVector(IList<T> list)
: base(list)
{}
// *** Protected Methods ***
protected override void ClearItems()
{
base.ClearItems();
this.PropertyChanged.Raise(this, o => o.Count);
this.PropertyChanged.Raise(this, o => o.Items);
this.OnVectorChanged(CollectionChange.Reset, 0);
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
this.PropertyChanged.Raise(this, o => o.Count);
this.PropertyChanged.Raise(this, o => o.Items);
this.OnVectorChanged(CollectionChange.ItemInserted, (uint)index);
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
this.PropertyChanged.Raise(this, o => o.Count);
this.PropertyChanged.Raise(this, o => o.Items);
this.OnVectorChanged(CollectionChange.ItemRemoved, (uint)index);
}
protected override void SetItem(int index, T item)
{
base.SetItem(index, item);
this.PropertyChanged.Raise(this, o => o.Items);
this.OnVectorChanged(CollectionChange.ItemChanged, (uint)index);
}
// *** Event Handlers ***
protected void OnVectorChanged(CollectionChange collectionChange, uint index)
{
this.OnVectorChanged(new VectorChangedEventArgs(collectionChange, index));
}
protected virtual void OnVectorChanged(IVectorChangedEventArgs e)
{
if (this.VectorChanged != null)
this.VectorChanged(this, e);
}
// *** Private Sub-classes ***
private class VectorChangedEventArgs : IVectorChangedEventArgs
{
// *** Fields ***
private readonly CollectionChange collectionChange;
private readonly uint index;
// *** Constructors ***
public VectorChangedEventArgs(CollectionChange collectionChange, uint index)
{
this.collectionChange = collectionChange;
this.index = index;
}
// *** Properties ***
public CollectionChange CollectionChange
{
get
{
return this.collectionChange;
}
}
public uint Index
{
get
{
return this.index;
}
}
}
}
}
I consider this temporary code - I assume that next versions of WinRT will have a native version of ObservableVector<T>.
I built a small sample application around to demonstrate the usage of the class in a MVVM application: all the work is done through data and command bindings. The app just manages two collections of Dragons: 'All Dragons' and 'Favorites'. The selected Dragon in each ListBox can be moved to the other collection by clicking the buttons in the middle. Here's how the app looks like:

By the way, in the current version of WinRT -Developer Preview- the collection changed events are only handled if T is object, so you have to define the collection as follows:
public ObservableVector<object> Dragons { get; set; }
For any other type -like ObservableVector<string> or ObservableVector<Dragon>- the change events will be simply ignored by the binding mechanism. That's another headache
.
You use the class exactly the same way as good old ObservableCollection, e.g. as ItemsSource to a an ItemControl:
<ListBox DataContext="{Binding}"
ItemsSource="{Binding Dragons}"
SelectedItem="{Binding SelectedDragon, Mode=TwoWay}" />
Here's the full source code, it's built with Visual Studio 11 Developer Preview: U2UConsult.WinRT.ObservableVector.Sample.zip (47,83 kb)
Enjoy!
- Posted by Diederik Krols on December 27, 2011
This article demonstrates how to databind a radiobutton to an enumeration element, in a WinRT Metro application. The MVVM viewmodel has a property of an enumeration type, which is bound to the IsChecked property of some radiobuttons. A value converter compares the value from the viewmodel with an enumeration element that is provided as parameter to the converter. The Convert method returns true if both match, the ConvertBack method updates the bound value when the radiobutton is clicked or tapped.
Here's a screenshot of the attached sample application. The radiobuttons are bound to the CarColor property -an enumeration- of the viewmodel. The Vote-button updates that same property through a command:

The converter is much more complex than the WPF version from my previous article, it's even more complex than its corresponding Silverlight version that you can find here.
Here's a list of reasons why the implementation was not so straightforward:
- The x:Static markup extension is not allowed in a Metro application,
- Binding.DoNothing does not exist in WinRT, and
- unlike in WPF or Silverlight, the converter receives the enumeration value as an integer instead of a string.
When I observed all of this, my first reaction was AARGH!!! Don't worry: it was not a call of anger and frustration. In the noble Antwerp language aerg just means 'this is bad'. Non-believers: just follow this link.
As a result, the converter is much more complex than expected. It reconstructs the enumeration parameter from the binding expression by string parsing and reflection. Here's how it looks like:
namespace U2UConsult.WinRT.Converters
{
using System;
using System.Globalization;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
/// <summary>
/// Converts an enum to a boolean.
/// </summary>
public class EnumToBooleanConverter : IValueConverter
{
/// <summary>
/// Compares the bound value with an enum param. Returns true when they match.
/// </summary>
public object Convert(object value, string typeName, object parameter, string language)
{
try
{
string parm = parameter.ToString();
int lastDot = parm.LastIndexOf(".");
string enumName = parm.Substring(0, lastDot);
string enumValue = parm.Substring(lastDot + 1);
Type t = Type.GetType(enumName);
string s = Enum.GetName(t, value);
object b = Enum.Parse(t, enumValue);
return b.ToString() == s;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Converts the boolean back into an enum.
/// </summary>
public object ConvertBack(object value, string typeName, object parameter, string language)
{
try
{
string parm = parameter.ToString();
int lastDot = parm.LastIndexOf(".");
string enumName = parm.Substring(0, lastDot);
string enumValue = parm.Substring(lastDot + 1);
Type t = Type.GetType(enumName);
object b = Enum.Parse(t, enumValue);
return b;
}
catch (Exception)
{
return DependencyProperty.UnsetValue;
}
}
}
}
In your application, all you need to do is create an enumeration:
public enum CarColor
{
Yellow,
Red,
Pink,
Black
}
In the viewmodel, create a property of the enumeration type:
private CarColor carColor = CarColor.Black;
public event PropertyChangedEventHandler PropertyChanged;
public CarColor CarColor
{
get { return carColor; }
set {
this.carColor = value;
this.PropertyChanged.Raise(this, (o) => o.CarColor);
}
}
The propertychanged notification makes sure that the radiobutton follows all modifications of the property.
In the view, define the converter instance as a resource in XAML:
<UserControl.Resources>
<cv:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</UserControl.Resources>
Bind the viewmodel's CarColor property to the Ischecked property of each radioButton. The enumeration value is provided as parameter to the converter with its fully qualified name. Also, you have to set the binding mode to TwoWay, and make sure that every radiobutton has its own GroupName. This is because we can't use Binding.DoNothing in the IValueConverter.ConvertBack Method. We always have to return the parameter, or DependencyProperty.UnsetValue. Both (re-)trigger all radiobuttons in the same group and that's not what we want; more info here.
Here's the full binding syntax in XAML:
<RadioButton Content="Giallo Modena"
GroupName="Yellow"
IsChecked="{Binding CarColor, Mode=TwoWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=U2UConsult.WinRT.DataBindingToEnum.ViewModels.CarColor.Yellow}" />
<RadioButton Content="Rosso Corsa"
GroupName="Red"
IsChecked="{Binding CarColor, Mode=TwoWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=U2UConsult.WinRT.DataBindingToEnum.ViewModels.CarColor.Red}" />
<RadioButton Content="Rosa Insapora"
GroupName="Pink"
IsChecked="{Binding CarColor, Mode=TwoWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=U2UConsult.WinRT.DataBindingToEnum.ViewModels.CarColor.Pink}" />
<RadioButton Content="Matte Nero"
GroupName="Black"
IsChecked="{Binding CarColor, Mode=TwoWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=U2UConsult.WinRT.DataBindingToEnum.ViewModels.CarColor.Black}" />
This solution is more error-prone and definitely slower than the WPF version, but it does the job. That's the good news. I also have bad news: the pink Ferrari photo is NOT photoshopped, aerg.
Anyway, here's the full source code. It was developed with Visual Studio 11 Developer Preview: U2UConsult.WinRT.DataBindingToEnum.zip (364,11 kb)
Enjoy!
- Posted by Diederik Krols on December 24, 2011
This article demonstrates how to databind a radiobutton to an enumeration element, in a WPF application. The MVVM viewmodel has a property of an enumeration type, which is bound to the IsChecked property of the radiobutton. A value converter compares the value from the viewmodel with an enumeration element that is provided as parameter to the converter. The Convert method returns true if both match, the ConvertBack method updates the bound value if there's no match.
Here's a screenshot of the attached sample application. The radiobuttons are bound to the Reindeer property -an enumeration- of the viewmodel. The Vote-button updates that same property through a command:

Here's the converter:
namespace U2UConsult.WPF.Converters
{
using System;
using System.Globalization;
using System.Windows.Data;
/// <summary>
/// Converts an enum to a boolean.
/// </summary>
public class EnumToBooleanConverter : IValueConverter
{
/// <summary>
/// Compares the bound value with an enum param. Returns true when they match.
/// </summary>
public object Convert(object value, Type targetType, object param, CultureInfo culture)
{
return value.Equals(param);
}
/// <summary>
/// Updates the bound value if it's different from the parameter.
/// </summary>
public object ConvertBack(object value, Type targetType, object param, CultureInfo culture)
{
return (bool)value ? param : Binding.DoNothing;
}
}
}
In your application, all you need to do is create an enumeration:
public enum Reindeer
{
Donner,
Blitzen,
Rudolph,
SantasLittleHelper
}
In the viewmodel, create a property of the enumeration type:
private Reindeer reindeer;
public event PropertyChangedEventHandler PropertyChanged;
public Reindeer Reindeer
{
get { return reindeer; }
set {
reindeer = value;
this.PropertyChanged.Raise(this, o => o.Reindeer);
}
}
The propertychanged notification makes sure that the radiobutton follows all modifications of the property.
In the view, define the converter instance as a resource in XAML:
<Window.Resources>
<cv:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</Window.Resources>
Bind the viewmodel's property to the Ischecked property of each radioButton. The enumeration value is provided as parameter to the converter. Don't use the string representation of the element's value, but use the x:Static markup extension:
<RadioButton Content="Donner"
IsChecked="{Binding Reindeer,
Converter={StaticResource EnumToBooleanConverter},
ConverterParameter={x:Static vm:Reindeer.Donner}}" />
<RadioButton Content="Blitzen"
IsChecked="{Binding Reindeer,
Converter={StaticResource EnumToBooleanConverter},
ConverterParameter={x:Static vm:Reindeer.Blitzen}}" />
There you go!
Here's the WPF project: U2UConsult.WPF.DataBindingToEnum.zip (41,39 kb)
Enjoy!
- Posted by Diederik Krols on December 15, 2011
This article describes a base class for WPF windows. It hides all GDI chrome, without losing functionality. WPF promises entire freedom in look-and-feel of your application. In its standard configuration, however, a WPF Window is still hosted in a classic GDI-based WinForm. Its border and header are rendered by the operating system. This takes away a lot of styling opportunities: things like a custom close button or rounded borders become impossible. On top of that, the GDI chrome eats a lot of pixels away from your application. That waste of space becomes obvious if you use custom controls like the popular Ribbon.
I created the NoGdiWindow base class to solve all of these problems. The following screenshots from the attached sample application show the same WPF window - with and without using the base class. If you prefer the left window, you may stop reading now
.
Hiding the GDI header
Setting the WindowStyle to System.Windows.WindowStyle.None removes the window header:
this.WindowStyle = System.Windows.WindowStyle.None;
You obviously loose the icon, the title and the minimize, maximize/restore, and close buttons. These are relatively easy to recover: the NoGdiWindow class contains the necessary commands and properties to rapidly create custom buttons in XAML. Here's an overview of the relevant class members:

Here's an example of a custom button:
<Button ToolTip="Maximize" Command="{Binding ElementName=Window, Path=MaximizeCommand}" Visibility="{Binding ElementName=Window, Path=MaximizeButtonVisibility}" />
Restoring the buttons is not sufficient: the beheaded window doesn't have a region anymore by which you can drag it, or minimize/restore by double-clicking. When using NoGdiWindow, all you need to do is create a region at the appropriate position and hook in the MouseLeftButtonDown event handler:
<Grid MouseLeftButtonDown="Header_MouseLeftButtonDown" Background="Transparent" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="32" Margin="80 0 0 0">
You may want to implement this functionality as a behavior instead of an event handler.
In the following screenshot, the region is highlighted. The left margin of 80 pixels keeps the ribbon's application menu accessible:

When you use WindowStyle.None your window will overlap the task bar if it's maximized. I personally don't mind at all. If you (or our end users) have a problem with this, you find some possible workarounds here.
Hiding the GDI border
You can make the remaining GDI border disappear by setting the AllowsTransparency property to True and your form's background to Transparent:
this.AllowsTransparency = true;
this.Background = new SolidColorBrush(Colors.Transparent);
This allows you to provide a rounded border around your window, or create an irregular shape. Unfortunately the native GDI border also hosts the resize handles, so you need to get these back. The NoGdiWindow draws a series of rectangles on the form, with the necessary mouse down handlers. Therefor, your main panel should be a Grid. In the following screenshot these rectangles are highlighted:

When the window is opened, it fetches its Win32 handle:
this.hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
When you hold the left mouse button inside one of the resize rectangles, the resize message is sent to the operating system through a SendMessage call:
SendMessage(this.hwndSource.Handle, 0x112, (IntPtr)(61440 + direction), IntPtr.Zero);
The resize code is based on this article by Joshua. Here's an overview of the relevant class members:

The AllowsTransparency is implemented through a technique called 'layered windows'. If you type these keywords in your [insert favorite search engine here], you'll immediately see that there are some issues under Windows XP. Your user interface may run without hardware acceleration on older XP releases, and it definitely ruins some WPF controls (tooltips, popups, comboboxes). There there are also issues with WindowsFormHost controls, regardless of the operating system you use. NoGdiWindow is aware or this, and has some defensive code around the property:
if ((Environment.OSVersion.Version.Major > 5) & (!this.UsesWindowsFormsHost))
{
// Activate Transparency
// ...
}
Code
Here's the sample project :U2UConsult.WPF.NoGdiWindow.zip (1.31 mb)
Enjoy!
- Posted by Diederik Krols on November 14, 2011
This article describes a reversible boolean-to-visibility valueconverter for WinRT and Metro.
Silverlight and WPF share lots of common ground, but Silverlight is restricted by the (lack of) complexity in its host, and certainly by the size of its footprint. As a result, Silverlight is missing some essential functionality: there's quite a lot of classes that we need to manually add to each and every project. WinRT and its Metro GUI are hardly restricted by footprint size, but they're still a lot closer to Silverlight than to the -ok, somewhat bloated- WPF.
As a result, WinRT is also missing some of that essential functionality. One example is the lack of a BooleanToVisibilityConverter. Any application that applies the MVVM pattern definitely has some places where boolean properties of a viewmodel determine whether or not parts of the GUI will be displayed. This is typically done through a valueconverter that translates boolean values into a Visibility. WPF has such a converter, but these ten lines of code seem to be too heavy for Silverlight and WinRT
.
Anyway, here's my version of a reversible converter for WinRT and Metro. It's based on Kent Boogaart's mother of all BooleanToVisibility converters:
namespace Mvvm
{
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
/// <summary>
/// Converts a Boolean into a Visibility.
/// </summary>
public class BooleanToVisibilityConverter : IValueConverter
{
/// <summary>
/// If set to True, conversion is reversed: True will become Collapsed.
/// </summary>
public bool IsReversed { get; set; }
public object Convert(object value, string typeName, object parameter, string language)
{
var val = System.Convert.ToBoolean(value);
if (this.IsReversed)
{
val = !val;
}
if (val)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, string typeName, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
You probably need one of each (True-to-Visible and False-to-Visible), and use these converters in a lot of different places. So it'a good idea to define the following application level resources, in App.xaml:
<Application xmlns="..."
xmlns:x="..."
xmlns:mvvm="using:Mvvm"
x:Class="...">
<Application.Resources>
<mvvm:BooleanToVisibilityConverter x:Key="TrueToVisibleConverter" />
<mvvm:BooleanToVisibilityConverter x:Key="FalseToVisibleConverter" IsReversed="True" />
</Application.Resources>
</Application>
Your viewmodels just need to define a boolean property, and notify its changes (see my previous article for the change notification methods):
public bool IsDay
{
get { return isDay; }
set
{
isDay = value;
this.PropertyChanged.Raise(this, o => o.IsDay);
}
}
Now the views can easily bind to the property and let the converters do their stuff:
<Image Source="/Images/Day.jpg"
Visibility="{Binding IsDay, Converter={StaticResource TrueToVisibleConverter}}" />
<Image Source="/Images/Night.jpg"
Visibility="{Binding IsDay, Converter={StaticResource FalseToVisibleConverter}}" />
Here are some screenshots from the attached sample project:


And here's the whole code: U2UConsult.WinRT.Boolean2Visibility.zip (311.89 kb)
Enjoy!
- Posted by Diederik Krols on October 27, 2011
This article presents a core MVVM framework for building Metro applications on the WinRT runtime.
With the WinRT runtime, Microsoft launched its fourth XAML-based platform - after WPf, Silverlight, and the Windows Phone. It's the fourth time they strongly advice development teams all over the world to get the maximum out of the power of XAML bindings, hence use the MVVM pattern in their applications. Strangely enough it's also the fourth time that they ship a runtime without the basic support for that same pattern. So it's up to the developers community to fill the gap.
The gap will be filled rapidly. While Microsoft Patterns & Practice's Prism team is still hesitating, Laurent Bugnion with his MVVM Light Toolkit and Rob Eisenberg with Caliburn Micro are definitely going for a WinRT version of their popular frameworks. But we're not going to sit and wait for these frameworks, are we? We want to start developing MVVM applications (in Metro-speak they're called 'apps') here and now.
In my ever humble opinion, the following three are the core requirements for using MVVM in an application :
- Raising the PropertyChanged event should be easy and typesafe.
- Defining a bindable command in a ViewModel should be easy and typesafe.
- Messaging between components should be easy and typesafe, and not create memory leaks.
I gleaned a core MVVM-framework with just three files - one for each requirement:

The namespace is Mvvm, so you can start each source code file with 'using Mvvm;'. Your manager will be impressed.
Change Notification
Most frameworks provide a base class that implements INotifyPropertyChanged. I'm a bit reluctant to use a scarse resource like inheritance- for such a triviality like just raising a standard event. Extension methods are much more flexible:
namespace Mvvm
{
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Windows.UI.Xaml.Data;
/// <summary>
/// Generic extension methods used by the framework.
/// </summary>
public static class ExtensionMethods
{
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
public static void Raise<T, P>(this PropertyChangedEventHandler pc, T source, Expression<Func<T, P>> pe)
{
if (pc != null)
{
pc.Invoke(source,
new PropertyChangedEventArgs(((MemberExpression)pe.Body).Member.Name));
}
}
/// <summary>
/// Raises the PropertyChanged event for all properties.
/// </summary>
public static void RaiseAll<T>(this PropertyChangedEventHandler pc, T source)
{
if (pc != null)
{
pc.Invoke(source, new PropertyChangedEventArgs(string.Empty));
}
}
}
}
Here's how a typical property looks like in a viewmodel or a model that implements INotifyPropertyChanged. Broadcasting a property value change is easy, ànd you get Intellisense support:
private string message
public string Message
{
get { return this.message; }
set
{
this.message = value;
this.PropertyChanged.Raise(this, o => o.Message);
}
}
It also definitely makes a good candidate for a code snippet...
Command binding
Most frameworks have an implementation of ICommand to be used specifically in viewmodels. Microsoft's RoutedCommand makes no sense there. Caliburn uses a radically different paradigm based on triggers and actions - the result is the same but it's further away from MVVM. The ICommand implementations in Prism and MVVM Light Toolkit have a constructor with just delegates for the Executed and CanExecute members. I prefer the RelayCommand implementation of the MVVM Light Toolkit, but I also prefer to call it DelegateCommand (sorry, Laurent) - the Prism terminology.
It's easy to use and it comes with a generic version:
namespace Mvvm
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Windows.UI.Xaml.Input;
using EventHandler = Windows.UI.Xaml.EventHandler;
public class DelegateCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
/// <summary>
/// Initializes a new instance of the DelegateCommand class that
/// can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public DelegateCommand(Action execute)
: this(execute, null)
{
}
/// <summary>
/// Initializes a new instance of the DelegateCommand class.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public DelegateCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
_execute = execute;
_canExecute = canExecute;
}
/// <summary>
/// Occurs when changes occur that affect whether the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged;
/// <summary>
/// Raises the <see cref="CanExecuteChanged" /> event.
/// </summary>
[SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",
Justification = "This cannot be an event")]
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">This parameter will always be ignored.</param>
/// <returns>true if this command can be executed; otherwise, false.</returns>
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">This parameter will always be ignored.</param>
public void Execute(object parameter)
{
if (CanExecute(parameter))
{
_execute();
}
}
}
}
Here's how to use the DelegateCommand. The ViewModel defines a command by providing just delegates, and provides implementations:
public ICommand UpdateTextCommand
{
get
{
return new DelegateCommand(this.UpdateTextCommand_Executed);
}
}
private void UpdateTextCommand_Executed()
{
// Command Logic
}
The View can bind to that command in XAML, no code-behind is needed:
<Button Content="Update Text" Command="{Binding UpdateTextCommand}" />
Event Aggregation
In an application that consists of different loosely-coupled components that need to publish and subscribe to events, it's not a good idea to rely on regular .NET events. More info can be found here. A so-called event aggregator is a much better solution. Prism's event aggregator may be the most powerful on the market, but the one from Caliburn Micro is easier to extract out of its framework. I just added the singleton pattern because I don't want to introduce an Inversion-of-Control container and bootstrappers in my three-file-framework.
Here's the full code of the Event Aggregator:
namespace Mvvm
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
/// <summary>
/// A marker interface for classes that subscribe to messages.
/// </summary>
public interface IHandle { }
/// <summary>
/// Denotes a class which can handle a particular type of message.
/// </summary>
/// <typeparam name = "TMessage">The type of message to handle.</typeparam>
public interface IHandle<TMessage> : IHandle
{
/// <summary>
/// Handles the message.
/// </summary>
/// <param name = "message">The message.</param>
void Handle(TMessage message);
}
/// <summary>
/// Enables loosely-coupled publication of and subscription to events.
/// </summary>
public interface IEventAggregator
{
/// <summary>
/// Gets or sets the default publication thread marshaller.
/// </summary>
/// <value>
/// The default publication thread marshaller.
/// </value>
Action<System.Action> PublicationThreadMarshaller { get; set; }
/// <summary>
/// Subscribes an instance to all events declared through implementations of <see cref = "IHandle{T}" />
/// </summary>
/// <param name = "instance">The instance to subscribe for event publication.</param>
void Subscribe(object instance);
/// <summary>
/// Unsubscribes the instance from all events.
/// </summary>
/// <param name = "instance">The instance to unsubscribe.</param>
void Unsubscribe(object instance);
/// <summary>
/// Publishes a message.
/// </summary>
/// <param name = "message">The message instance.</param>
/// <remarks>
/// Uses the default thread marshaller during publication.
/// </remarks>
void Publish(object message);
/// <summary>
/// Publishes a message.
/// </summary>
/// <param name = "message">The message instance.</param>
/// <param name = "marshal">Allows the publisher to provide a custom thread marshaller for the message publication.</param>
void Publish(object message, Action<System.Action> marshal);
}
/// <summary>
/// Enables loosely-coupled publication of and subscription to events.
/// </summary>
public class EventAggregator : IEventAggregator
{
/// <summary>
/// The default thread marshaller used for publication;
/// </summary>
public static Action<System.Action> DefaultPublicationThreadMarshaller = action => action();
private static IEventAggregator instance;
readonly List<Handler> handlers = new List<Handler>();
/// <summary>
/// Initializes a new instance of the <see cref = "EventAggregator" /> class.
/// </summary>
public EventAggregator()
{
PublicationThreadMarshaller = DefaultPublicationThreadMarshaller;
}
/// <summary>
/// Gets the singleton instance.
/// </summary>
public static IEventAggregator Instance
{
get
{
if (instance == null)
{
instance = new EventAggregator();
}
return instance;
}
}
/// <summary>
/// Gets or sets the default publication thread marshaller.
/// </summary>
/// <value>
/// The default publication thread marshaller.
/// </value>
public Action<System.Action> PublicationThreadMarshaller { get; set; }
/// <summary>
/// Subscribes an instance to all events declared through implementations of <see cref = "IHandle{T}" />
/// </summary>
/// <param name = "instance">The instance to subscribe for event publication.</param>
public virtual void Subscribe(object instance)
{
lock (handlers)
{
if (handlers.Any(x => x.Matches(instance)))
return;
handlers.Add(new Handler(instance));
}
}
/// <summary>
/// Unsubscribes the instance from all events.
/// </summary>
/// <param name = "instance">The instance to unsubscribe.</param>
public virtual void Unsubscribe(object instance)
{
lock (handlers)
{
var found = handlers.FirstOrDefault(x => x.Matches(instance));
if (found != null)
handlers.Remove(found);
}
}
/// <summary>
/// Publishes a message.
/// </summary>
/// <param name = "message">The message instance.</param>
/// <remarks>
/// Does not marshall the the publication to any special thread by default.
/// </remarks>
public virtual void Publish(object message)
{
Publish(message, PublicationThreadMarshaller);
}
/// <summary>
/// Publishes a message.
/// </summary>
/// <param name = "message">The message instance.</param>
/// <param name = "marshal">Allows the publisher to provide a custom thread marshaller for the message publication.</param>
public virtual void Publish(object message, Action<System.Action> marshal)
{
Handler[] toNotify;
lock (handlers)
toNotify = handlers.ToArray();
marshal(() =>
{
var messageType = message.GetType();
var dead = toNotify
.Where(handler => !handler.Handle(messageType, message))
.ToList();
if (dead.Any())
{
lock (handlers)
{
dead.Apply(x => handlers.Remove(x));
}
}
});
}
protected class Handler
{
readonly WeakReference reference;
readonly Dictionary<TypeInfo, MethodInfo> supportedHandlers = new Dictionary<TypeInfo, MethodInfo>();
public Handler(object handler)
{
reference = new WeakReference(handler);
var handlerInfo = typeof(IHandle).GetTypeInfo();
var interfaces = handler.GetType().GetTypeInfo().ImplementedInterfaces
.Where(x => handlerInfo.IsAssignableFrom(x.GetTypeInfo()) && x.IsGenericType);
foreach (var @interface in interfaces)
{
var type = @interface.GenericTypeArguments[0];
var method = @interface.GetTypeInfo().DeclaredMethods.First(x => x.Name == "Handle");
supportedHandlers[type.GetTypeInfo()] = method;
}
}
public bool Matches(object instance)
{
return reference.Target == instance;
}
public bool Handle(Type messageType, object message)
{
var target = reference.Target;
if (target == null)
return false;
var typeInfo = messageType.GetTypeInfo();
foreach (var pair in supportedHandlers)
{
if (pair.Key.IsAssignableFrom(typeInfo))
{
pair.Value.Invoke(target, new[] { message });
return true;
}
}
return true;
}
}
}
/// <summary>
/// Generic extension methods used by the framework.
/// </summary>
public static class EventAggregatorExtensionMethods
{
/// <summary>
/// Applies the action to each element in the list.
/// </summary>
/// <typeparam name="T">The enumerable item's type.</typeparam>
/// <param name="enumerable">The elements to enumerate.</param>
/// <param name="action">The action to apply to each item in the list.</param>
public static void Apply<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
action(item);
}
}
}
Here's how to use it. Please note that I'm just passing messages of type String, you might want to define your own event payload classes. A publisher just needs to get a reference to the central even handler, and publish its message:
EventAggregator.Instance.Publish(this.Message);
The subscriber registers himself to the same event aggregator. He specifies the type of message he's interested in by implementing the IHandle<T> interface:
class SubscriberViewModel : INotifyPropertyChanged, IHandle<string>
{
public SubscriberViewModel()
{
// Subscribe
EventAggregator.Instance.Subscribe(this);
}
public void Handle(string message)
{
// Event handling comes here
}
}
Publisher and subscriber never have a reference to each other, while the event aggregator uses weak references. This results in a memory-leak free pattern.
Sample
I built a small and simple application (oops, I did it again: app) to test drive the framework. Here's how it looks like:

On the left side of the screen, there's a text balloon and a button. These belong to the publisher. Clicking the button updates the Message property and via the change notification extension methods also the GUI. It sends the new value as message through the event aggregator. The text balloon in the middle belongs to a subscriber that is instantiated using a view-first approach: the view instantiates its viewmodel. Typically this is done by defining its data context in XAML - but that does not seem to work yet, so I needed some code behind. The text balloon on the right belongs to another subscriber. This one is instantiated using the viewmodel-first approach. When the datacontext of a control is set to a viewmodel, the control decides what template to load. This is typically done with typed data templates in WPF, or with a value converter in Silverlight. Since typed data templates are not available in Metro, I used the Silverlight approach. [Note: The IValueConverter interface in Metro is different from its predecessors.] Both subscribers receive the message through the event aggregator subscription, and use the change notification extensions methods it to update their own Message property, populating the text balloon.
Source Code
Here's the full source code. It requires VS 2011 Developer Preview: U2UConsult.WinRT.MVVM.zip (205,86 kb)
Enjoy!
- Posted by Diederik Krols on April 24, 2011
Prism 4.0, Managed Extensibility Framework, and Silverlight 4.0 provide an ideal combination to develop robust and flexible enterprise applications. This article explains how you can keep the Prism module catalog in such an application on the server side. In most of the Prism Quickstarts, the module catalog is embedded in the shell:

The application class starts the bootstrapper:
private void Application_Startup(
object sender,
StartupEventArgs e)
{
ApplicationBootstrapper bootstrapper = new ApplicationBootstrapper();
bootstrapper.Run();
}
The bootstrapper builds the catalog from the local file:
protected override IModuleCatalog CreateModuleCatalog()
{
ModuleCatalog catalog = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri("Prism.Sample.Shell;component/Modules/ModuleCatalog.xaml", UriKind.Relative));
return catalog;
}
Unfortunately, this setup requires a rebuild and a redeploy of the shell application whenever a change in the catalog is needed (e.g. to add an extra module, or to remove a buggy module). In most -if not all- real-world scenarios it makes more sense to place the catalog in an area that allows easy modification. The following solution has the catalog in a file on the server side, but you can easily go for other storage locations, like a database table, a WCF service or a SharePoint list. Here's where the file is kept:

The bootstrapper gets an extra constructor that takes a stream:
private Stream stream;
public ApplicationBootstrapper(Stream stream)
{
this.stream = stream;
}
This stream is used to build the catalog:
protected override IModuleCatalog CreateModuleCatalog()
{
ModuleCatalog catalog = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(this.stream);
return catalog;
}
On application startup, the file is read, wrapped in a stream, and handed over to the bootstrapper:
private void Application_Startup(
object sender,
StartupEventArgs e)
{
WebClient client = new WebClient();
client.OpenReadCompleted += this.Client_OpenReadCompleted;
client.OpenReadAsync(new System.Uri(@"Modules\ModuleCatalog.xaml", System.UriKind.Relative));
}
private void Client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
ApplicationBootstrapper bootstrapper = new ApplicationBootstrapper(e.Result);
bootstrapper.Run();
}
The following two projects demonstrate both approaches. The application is a small Prism-MEF-Silverlight tutorial application that I wrote a couple of months ago. Here's how it looks like:

Here's the project before and after the modification (it contains the Prism dll's, so you might need to unblock these):
Enjoy !
- Posted by Diederik Krols on April 1, 2011
Here's the bad news: there are two very common things that should be easy, but can NOT be done in Team Foundation Server.
- You can not switch an existing team project to a new set of process templates.
- You can not rename a team project.
These are two show stoppers when you have a team project containing a couple of man years of coding, and you want to migrate to e.g. the Microsoft Visual Studio Scrum 1.0 templates.
Here's the good news: the show can go on! You cán migrate a TFS team project to an new process template in a supported way, and with just minimum loss of information. It just takes a lot more effort -and guts- than it should take.
Here's a procedure:
Step 1: Create a (new) backup team project.
You need a backup project to temporarily host all data. It doesn't matter what process templates you select for this project, since you're going to lose the work item tracking anyway. In most situations that's not a real problem: you probably decided to migrate to another process template because you didn't like your current work items...

Step 2: Copy the files and their version history to this new project.
This sounds easy, but it can't be done with the standard toolset. For this task you need to download and install the Team Foundation Integration Tools, a platform developed by the Visual Studio ALM Rangers. The TFS Integration Tools come in two flavors:
For this type of TFS-to-TFS migration the March 2011 release of the non-bleeding version is OK, and it's fully supported by our friends in Redmond - you never know...
The TFS Integration Tools are not really lightweight. You'll need an extra SQL Server database -SQL Express is good enough if you don't hit the 4GB size limit- and two Windows services will be installed:
The backup project should be populated through a new migration from TFS to TFS, with VersionHistory only. Your project's work item tracking will be lost if you migrate to a project with another process template. Here are the two configuration screens. The configuration will be persisted in the database:


The tool will store the source project's metadata in a database. It then populates the target project by replaying all check-in activities through the API of TFS, controlled by a windows service.
During the process, you might need to solve some minor conflicts, e.g. regarding the build template xaml files:

Whilst the migration is running, you can sit back and relax, and keep an eye on the process:

Step 3: Delete the original team project.
This is by far the most scary step, but it's necessary if you want to reuse the original project name. It's a step that can not be performed from Visual Studio: you need to do this via the TFS Administration Console. Here are the buttons and the checkboxes that will remove all traces of several man years of development in just a couple of seconds:

The rest of the story is obvious: you need to re-run everything in the opposite direction.
Step 4: Recreate the project.
Make sure to select the correct process templates.
Step 5: Repopulate the new project from the the backup project.
Reselect TFS-to-TFS, and keep VersionHistory.
And there you are!
- Posted by Diederik Krols on March 26, 2011
Here's a nice little extension method that returns a deep copy of a relatively simple object - like an Entity or a Data Transfer Object. It is based on the DataContractSerializer, so the object should be serializable through XML or a DataContract.
The extension works from Silverlight 2 upwards:
public static class GenericExtensions
{
public static T Clone<T>(this T source)
{
DataContractSerializer dcs = new DataContractSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
dcs.WriteObject(ms, source);
ms.Position = 0;
return (T)dcs.ReadObject(ms);
}
}
}
Enjoy!