title: How to group child objects from one List in a TreeView?
body: <p>How do I take a List and then in a TreeView group them by their Class? I read <a href="http://www.codeproject.com/Articles/36451/Organizing-Heterogeneous-Data-on-a-WPF-TreeView.aspx" rel="nofollow">this</a>, but it doesn't group the child objects, it just has the related properties in collections instead.</p>
  
  <ul>
  <li>Warehouse
  <ul>
  <li>Type A
  <ul>
  <li>Subtype 1</li>
  <li>Subtype 2</li>
  </ul></li>
  <li>Type B</li>
  <li>Type C</li>
  </ul></li>
  </ul>
  
  <p>If I have List that have all those types in there how do I show the grouping in a TreeView?</p>
  
  <p>Before, I was manually adding them in, one TreeViewItem at a time.</p>
  
  <pre><code>List&lt;Warehouse&gt; myWarehouse = new List&lt;Warehouse&gt;();
  TreeViewItem WarehouseNode = new TreeViewItem() { Header = "Warehouse" };
  TreeViewItem TypeANode = new TreeViewItem() { Header = "Type A" };
  foreach(SubtypeA type in myWarehouse) {
      TypeANode.Items.Add(new TreeViewItem() { Header = type.Name };
  }
  WarehouseNode.Items.Add(TypeANode);
  etc. for Type B and Type C.
  </code></pre>
  
  <p>I was reading about <a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=hierarchicaldatatemplate&amp;source=web&amp;cd=1&amp;cad=rja&amp;ved=0CC8QFjAA&amp;url=http://msdn.microsoft.com/en-us/library/system.windows.hierarchicaldatatemplate.aspx&amp;ei=U2DUUa2ZPMrC4AOauYHICg&amp;usg=AFQjCNF5bqK83UYRUTvbAcCzXuz25NOAnA&amp;bvm=bv.48705608,d.dmg" rel="nofollow">HierarchicalDataTemplate</a> and it looks like this is how I want to go, using an <a href="http://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=itemtemplateselector&amp;source=web&amp;cd=2&amp;cad=rja&amp;ved=0CDMQFjAB&amp;url=http://msdn.microsoft.com/en-us/library/system.windows.hierarchicaldatatemplate.itemtemplateselector.aspx&amp;ei=gGDUUfrMKLD64AP1jIHgCw&amp;usg=AFQjCNHgGBXdRFGY7YkO7d2ScrHj3WA2zw&amp;bvm=bv.48705608,d.dmg" rel="nofollow">ItemTemplateSelector</a> to change the DataTemplate.</p>
  
  <p>So, I started working with <code>HierarchicalDataTemplates</code> and came up with the below.</p>
  
  <p>XAML:</p>
  
  <pre><code>&lt;Window.Resources&gt;
      &lt;Utility:MyTemplateSelector x:Key="MyTemplateSelector" /&gt;
      &lt;HierarchicalDataTemplate x:Key="TypeCTemplate" DataType="{x:Type EntityType:TypeC}"
                                ItemsSource="{Binding OBJS}" ItemTemplateSelector="{StaticResource MyTemplateSelector}"&gt;
          &lt;TextBlock Text="Type C"/&gt;
      &lt;/HierarchicalDataTemplate&gt;
      &lt;HierarchicalDataTemplate x:Key="TypeBTemplate" DataType="{x:Type EntityType:TypeB}"
                                ItemsSource="{Binding OBJS}" ItemTemplateSelector="{StaticResource MyTemplateSelector}"&gt;
          &lt;TextBlock Text="Type B"/&gt;
      &lt;/HierarchicalDataTemplate&gt;
      &lt;HierarchicalDataTemplate x:Key="TypeATemplate" DataType="{x:Type EntityType:TypeA}"
                                ItemsSource="{Binding OBJS}" ItemTemplateSelector="{StaticResource MyTemplateSelector}"&gt;
          &lt;TextBlock Text="Type A"/&gt;
      &lt;/HierarchicalDataTemplate&gt;
  &lt;/Window.Resources&gt;
  &lt;Grid&gt;
      &lt;TreeView Name="MyTreeView" ItemsSource="{Binding OBJS}" 
                ItemTemplateSelector="{StaticResource MyTemplateSelector}"&gt;
      &lt;/TreeView&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p>I wrote a <code>DataTemplateSelector</code>:</p>
  
  <pre><code>class MyTemplateSelector : DataTemplateSelector {
      public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) {
          MethodInfo mi = container.GetType().GetMethod("FindResource") as MethodInfo;
          if(mi != null) {
              string strItem = item.ToString().Split('.').Last();
              switch(item.ToString().Split('.').Last()) {
                  case "Type A":
                      return mi.Invoke(container, new object[] { "TypeATemplate" }) as DataTemplate;
                  case "Type B":
                      return mi.Invoke(container, new object[] { "TypeBTemplate" }) as DataTemplate;
                  case "Type C":
                      return mi.Invoke(container, new object[] { "TypeCTemplate" }) as DataTemplate;
              }
  
              return null;
          }
  
          return null;
      }
  }
  </code></pre>
  
  <p>But now, when I look at the TreeView, it gives me this:</p>
  
  <ul>
  <li>Type B</li>
  <li>Type B</li>
  <li>Type B</li>
  <li>Type C</li>
  <li>etc.</li>
  </ul>