title: WPF - Binding to CheckBox not working in a HierarchicalDataTemplate
body: <p>In a WPF treeview I am trying to automatically check the children if the parent node is being checked. I am using a view model for that and a bindable object for the nodes, however all my attempts failed. Here is the code (C# + XAML). Any ideas would be greatly appreciated</p>
  
  <pre><code>&lt;Window x:Class="TestCheckBoxBinding.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:TestCheckBoxBinding"
  Title="Window1" Height="300" Width="300"&gt;
  &lt;Window.Resources&gt;
      &lt;Style TargetType="{x:Type TreeViewItem}"&gt;
          &lt;Setter Property="IsExpanded" Value="True"/&gt; 
      &lt;/Style&gt;
      &lt;HierarchicalDataTemplate DataType="{x:Type local:TestCategory}" ItemsSource="{Binding Tests, Mode=OneTime}"&gt;
          &lt;Label Content="{Binding Name}"&gt;&lt;/Label&gt;
      &lt;/HierarchicalDataTemplate&gt;
      &lt;HierarchicalDataTemplate DataType="{x:Type local:Test}" ItemsSource="{Binding Children, Mode=OneTime}"&gt;
          &lt;StackPanel Orientation="Horizontal"&gt;
              &lt;CheckBox VerticalAlignment="Center"  IsChecked="{Binding IsChecked, Mode=TwoWay}"&gt;&lt;/CheckBox&gt;
              &lt;Label Content="{Binding Name}"&gt;&lt;/Label&gt;
          &lt;/StackPanel&gt;
      &lt;/HierarchicalDataTemplate&gt;
  &lt;/Window.Resources&gt;
  &lt;Grid&gt;
      &lt;TreeView ItemsSource="{Binding Categories, Mode=OneTime}"&gt;&lt;/TreeView&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p></p>
  
  <pre><code>public class TestsViewModel
  {
      public static void PopulateList(TestsViewModel vm)
      {
          TestCategory cat1 = new TestCategory() { Id = 1, Name = "First category" };
          Test t1 = new Test() { Name = "Test1" };
          Test t2 = new Test() { Name = "Test2" };
          Test t3 = new Test() { Name = "Test3" };
          t1.AddChild(t2);
          t1.AddChild(t3);
          Test t4 = new Test() { Name = "Test4" };
          cat1.AddTest(t1);
          cat1.AddTest(t4);
          vm.AddTestCategory(cat1);
          TestCategory cat2 = new TestCategory() { Id = 2, Name = "Second category" };
          Test t5 = new Test() { Name = "Test1" };
          Test t6 = new Test() { Name = "Test2" };
          Test t7 = new Test() { Name = "Test3" };
          t6.AddChild(t7);
          Test t8 = new Test() { Name = "Test4" };
          cat2.AddTest(t5);
          cat2.AddTest(t6);
          cat2.AddTest(t8);
          vm.AddTestCategory(cat2);
      }
      private readonly IEnumerable&lt;TestCategory&gt; categories = new List&lt;TestCategory&gt;();
      public IEnumerable&lt;TestCategory&gt; Categories { get { return categories; } }
      public void AddTestCategory(TestCategory testCategory)
      {
          ((IList&lt;TestCategory&gt;)categories).Add(testCategory);
      }
  }
  
  public class TestCategory
  {
      public int Id { get; set; }
      public string Name { get; set; }
      private readonly IEnumerable&lt;Test&gt; tests = new List&lt;Test&gt;();
      public IEnumerable&lt;Test&gt; Tests { get { return tests; } }
      public void AddTest(Test t)
      {
          ((IList&lt;Test&gt;)tests).Add(t);
      }
  }
  
  public class Test : INotifyPropertyChanged
  {
      private string name;
      public string Name
      {
          set
          {
              if (name != value)
              {
                  name = value;
                  this.OnPropertyChanged("Name");
              }
          }
          get { return name; }
      }
  
      public bool? isChecked = false;
      public bool? IsChecked
      {
          get { return isChecked; }
          set
          {
              if (isChecked != value)
              {
                  isChecked = value;
                  if (children.Count() &gt; 0)
                  {
                      foreach (var test in children)
                      {
                          test.isChecked = value;
                          test.Name += ".";
                      }
                  }
                  this.OnPropertyChanged("IsChecked");
              }
          }
      }
  
      public void AddChild(Test test)
      {
          ((IList&lt;Test&gt;)children).Add(test);
      }
  
      private readonly IEnumerable&lt;Test&gt; children = new List&lt;Test&gt;();
      public IEnumerable&lt;Test&gt; Children
      {
          get { return children; }
      }
  
      #region INotifyPropertyChanged Members
  
      // Create the OnPropertyChanged method to raise the event
      protected void OnPropertyChanged(string propName)
      {
          PropertyChangedEventHandler handler = PropertyChanged;
          if (handler != null)
          {
              handler(this, new PropertyChangedEventArgs(propName));
          }
      }
  
      public event PropertyChangedEventHandler PropertyChanged;
  
      #endregion
  }
  </code></pre>