UWP-Apps - First Steps [Part 1]

22.03.2016 Programming .NET C# UWP WPF

As a mainly WPF developer, I decided to take a look at the new Universal Windows Platform (UWP). In this post, I will focus on some small differences between WPF and UWP, including StringFormat and DataTemplates.

Binding StringFormat

The most common use of StringFormat in Bindings for me is to format DateTimes and Numbers.

1<TextBox Text="{Binding Date, StringFormat={}{dd.MM.yyyy}}" />

In UWP, Bindings don’t provide a StringFormat property. The solution is to create a converter that takes the desired date format as parameter. Using this converter would then look like this:

 1<!-- ResourceDictionary in App.xaml -->
 2<!-- Converter -->
 3<converter:DateTimeStringFormatConverter x:Key="DateTimeStringFormatConverter" />
 4
 5<!-- Constants -->
 6<x:String x:Key="DateFormatString">dd.MM.yyyy</x:String>
 7
 8<!-- View.xaml -->
 9<TextBox Text="{Binding CurrentTime,
10                        Converter={StaticResource DateTimeStringFormatConverter},
11                        ConverterParameter={StaticResource DateFormatString}}" />

DataTemplates

1<!-- ResourceDictionary in App.xaml -->
2<DataTemplate DataType="{x:Type vm:InfoViewModel}">
3    <v:Info />
4</DataTemplate>
5
6<!-- MainWindow.xaml -->
7<ContentControl Content="{Binding MainContent}" />

In WPF, I often used a ContentControl along with some DataTemplates to dynamically display content (controlled by the ViewModel). The DataTemplates would define a View for each ViewModel. For some reasons, this isn’t quite as easy in a UWP App (UWP seems to resolve Datatemplates at compile time, not at execution time like WPF). The solution is to supply a custom DataTemplateSelector class.

 1public class CustomTemplateSelector : DataTemplateSelector
 2{
 3    private static readonly IDictionary<Type, DataTemplate> DataTemplates;
 4
 5    static CustomTemplateSelector()
 6    {
 7        DataTemplates = new Dictionary<Type, DataTemplate>
 8        {
 9            { typeof(MyViewModel), Application.Current.Resources["MyDataTemplate"] as DataTemplate },
10        };
11    }
12
13    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
14    {
15        if (item == null)
16        {
17            return null;
18        }
19
20        Type viewModelType = item.GetType();
21        return DataTemplates.ContainsKey(viewModelType) ? DataTemplates[item.GetType()] : null;
22    }
23}
1<ContentControl Content="{Binding MainContent}" ContentTemplateSelector="{StaticResource CustomTemplateSelector}" />

The CustomTemplateSelector keeps references to DataTemplates in a Dictionary. I consider directly reading them from the application resources a code smell, but I couldn’t think of an elegant solution yet.

Related posts

... some things you might also be interested in

LegacyWrapper 3.0 released
02.02.2019 | Programming | .NET C# Legacy Wrapper
LegacyWrapper 2.1 is out!
20.08.2017 | Programming | .NET C# Legacy Wrapper
Invoking an unmanaged 32bit library out of a 64bit process
28.09.2015 | Programming | .NET C# Legacy Wrapper