title: UWP DataTemplates for multiple item types in ListView
body: <p>How would I go about implementing this?</p>
  
  <p>Let's say this is my model:</p>
  
  <pre><code>public interface IAnimal
  {
       string Name { get; }
  }
  public class Fish : IAnimal
  {
      public string Name { get; set; }
      public int ScalesCount { get; set; }
  }
  public class Dog : IAnimal
  {
      public string Name { get; set; }
      public string CollarManufacturerName { get; set; }
  }
  
  public class ViewModel
  {
      public ObservableCollection&lt;IAnimal&gt; Animals { get; set; }
  
      public ViewModel()
      {
          this.Animals = new ObservableCollection&lt;IAnimal&gt;();
          this.Animals.Add(new Fish { Name = "Carl", ScalesCount = 9000 });
          this.Animals.Add(new Dog { Name = "Fifi", CollarManufacturerName = "Macrosoft" });
      }
  }
  </code></pre>
  
  <p><em>For the sake of the amount of code in this question please assume that <code>INotifyPropertyChanged</code> is implemented where necessary, and that the ViewModel is correctly initialized in the page.</em></p>
  
  <p>How can I use my own corresponding DataTemplates? In WPF I would just define multiple DataTemplates without an <code>x:Key</code> but with a defined DataType and let the ListView chose which to use based on the type of the item. UWP doesn't like that; the compiler simply states <code>Dictionary Item "DataTemplate" must have a Key attribute</code>. So how do I accomplish my goal?</p>
  
  <h1>Current Attempt</h1>
  
  <p>My current attempt is to make a custom <code>DataTemplateSelector</code>, which seems rather straight forward.</p>
  
  <pre><code>public class MyDataTemplateSelector: Windows.UI.Xaml.Controls.DataTemplateSelector
  {
      public ObservableCollection&lt;TemplateMatch&gt; Matches { get; set; }
  
      public DataTemplateSelector()
      {
          this.Matches = new ObservableCollection&lt;TemplateMatch&gt;();
      }
  
      protected override DataTemplate SelectTemplateCore(object item)
      {
          return this.Matches.FirstOrDefault(m =&gt; m.TargetType.Equals(item))?.Template;
      }
  
      protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
      {
          return this.Matches.FirstOrDefault(m =&gt; m.TargetType.Equals(item))?.Template;
      }
  }
  
  public class TemplateMatch
  {
      public Type TargetType { get; set; }
      public DataTemplate Template { get; set; }
  }
  </code></pre>
  
  <p>Define it in XAML like this:</p>
  
  <pre><code>&lt;ListView ItemsSource="{x:Bind ViewModel.Animals}"&gt;
      &lt;ListView.ItemTemplateSelector&gt;
          &lt;cmp:MyDataTemplateSelector&gt;
              &lt;cmp:MyDataTemplateSelector.Matches&gt;
                  &lt;cmp:TemplateMatch TargetType="model:Dog" Template="{StaticResource DogTemplate}"/&gt;
                  &lt;cmp:TemplateMatch TargetType="model:Fish" Template="{StaticResource FishTemplate}"/&gt;
              &lt;/cmp:MyDataTemplateSelector.Matches&gt;
          &lt;/cmp:MyDataTemplateSelector&gt;
      &lt;/ListView.ItemTemplateSelector&gt;
  &lt;/ListView&gt;
  </code></pre>
  
  <p>Unfortunately when I run this, an Exception occurs during runtime, stating <code>Failed to create a 'Ui.Components.TemplateMatch' from the text 'model:Dog'.</code> So it seems binding to a <code>Type</code> property is not that easy.</p>
  
  <p>Any help is appreciated!</p>
  
  <p>Please note that I'd like to use a property of type <code>Type</code>, as opposed to <code>string</code> where I would pass the CLR type name and using reflection to invoke the type, mostly because I don't want mixed CLR and XML namespaces appear in XAML. If you can find a way to invoke the type using the XML namespace, I'll gladly take that as an answer.</p>