title: DataTemplates and Generics
body: <p>I have read nearly a thousand posts explaining that setting a closed generic type as <code>DataType</code> on a <code>DataTemplate</code> does not work, because WPF wouldn't support that. But as a matter of fact, this is just wrong.</p>
  
  <p>I can define the following <code>DataTemplate</code> in my <code>Window.Resources</code> and it will be used when I assign a list of strings to a content control. For example:</p>
  
  <pre><code>&lt;Window x:Class="WpfApp1.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:System="clr-namespace:System;assembly=mscorlib"
          xmlns:Generic="clr-namespace:System.Collections.Generic;assembly=mscorlib"
          mc:Ignorable="d"
          Title="MainWindow" Height="450" Width="800"&gt;
      &lt;Window.Resources&gt;
          &lt;DataTemplate DataType="{x:Type TypeName=Generic:List`1[System.String]}"&gt;
              &lt;TextBlock Text="Hi List of Strings"
                         FontSize="40"
                         Foreground="Cyan"/&gt;
          &lt;/DataTemplate&gt;
      &lt;/Window.Resources&gt;
      &lt;Grid&gt;
          &lt;ContentControl x:Name="_contentControl"&gt;
          &lt;/ContentControl&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>and in code-behind:</p>
  
  <pre><code>public partial class MainWindow : Window
  {
      public MainWindow()
      {
          InitializeComponent();
          _contentControl.Content = new List&lt;string&gt; { "Huhu" };
      }
  }
  </code></pre>
  
  <p>With this setup you will see "Hi List of Strings". For me that's the proof that I can define generic types as <code>DataType</code>. But I want to take it one step further: I'd like to define a <code>Dictionary&lt;string, string&gt;</code> as <code>DataType</code>. But unfortunately, I can't get it to work.</p>
  
  <p><strong>So the question is</strong>: How can I define a <code>Dictionary&lt;string, string&gt;</code> as <code>DataType</code> of a <code>DataTemplate</code>?</p>
  
  <p>If you know the answer, you can stop reading. But since it is good practice to show what I already did, I keep writing.
  <strong>What did I do already?</strong>
  At first I went brute-force and tried several combinations similar to:</p>
  
  <pre><code>- DataType="{x:Type TypeName=Generic:Dictionary`2[System.String];[System.String]}"
  - DataType="{x:Type TypeName=Generic:Dictionary`2[System.String],[System.String]}"
  - DataType="{x:Type TypeName=Generic:Dictionary`2[System.String,System.String]}"
  </code></pre>
  
  <p>But since none of them worked, I dove into <code>System.Xaml</code> and looked at <code>TypeExtension</code>, <code>GenericTypeNameParser</code> and <code>GenericTypeNameScanner</code>, because I thought that these are the codelines which resolve the type. But looking at the code I realized that ` is an invalid character.</p>
  
  <p>To prove it, I wrote my own <code>MarkupExtension</code></p>
  
  <pre><code>public class UseTheTypeExtensionsParser : MarkupExtension
  {
      public override object ProvideValue(IServiceProvider serviceProvider)
      {
          var a = new TypeExtension("Generic:List`1[[System.String]]");
          var type = a.ProvideValue(serviceProvider);
          return type.ToString();
      }
  }
  </code></pre>
  
  <p>and used it as follows:</p>
  
  <pre><code>&lt;Window x:Class="WpfApp1.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:System="clr-namespace:System;assembly=mscorlib"
          xmlns:Generic="clr-namespace:System.Collections.Generic;assembly=mscorlib"
          xmlns:WpfApp1="clr-namespace:WpfApp1"
          mc:Ignorable="d"
          Title="MainWindow" Height="450" Width="800"&gt;
      &lt;Grid&gt;
          &lt;ContentControl Content="{WpfApp1:UseTheTypeExtensionsParser}"/&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>And this threw the exception that the character ` was not expected and that the XAML-type is invalid.</p>
  
  <p>That got me wondering why my first example worked. I think, that on markup-compiling the XAML for WPF, it is not the <code>TypeExtension</code> that is used for resolving the XamlType, but i think that the <code>XamlNamespace</code> is used. Because this class has the <code>MangleGenericTypeName</code>-method which uses the `-character.
  But I still can't see the code which extracts the type arguments, so I cannot see the correct syntax to specify the type arguments for the Dictionary. This is where I am stuck.</p>
  
  <p>(Needless to say that the Microsoft-Docs are worthless on this topic.)</p>
  
  <p><strong>Edit</strong>: Since it seems unclear why I want this, I will explain it: I want the automatic selection of a <code>ContentTemplate</code> of the <code>ContentControl</code>. And of course: my constructed <code>DataTemplate</code> in the example is very simple. But everyone should be able to imagine, that I want different DataTemplates for Lists, for Dictionaries or for simple strings.</p>
  
  <p>I have a ViewModel which has a <code>public object Result { get; }</code> Property. And sometimes, the result is an int, sometimes a string, sometimes a List and so on and so forth. I am binding this <code>Result</code>-property to the <code>Content</code>-Property of a <code>ContentControl</code>. And for all the types mentioned, I wrote different DataTemplates which are automatically selected by WPF. So <code>int</code>s are shown in a <code>Rectangle</code> and <code>String</code>s are shown in an <code>Ellipse</code>.</p>
  
  <p>After I got all this to work, I want another <code>DataTemplate</code>, but this time for a <code>Dictionary</code>.</p>