title: Databinding with TreeView in WPF
body: <p>I am working with data binding and tree views and I am not able to get my TreeView to populate in my WPF. I think I am relatively close, just a small tweak somewhere, but I can't seem to find it.</p>
  
  <p>Here's my Project class:</p>
  
  <pre><code>public class Project
  {
      public Project(string Name, bool isFolder, Project ParentFolder)
      {
          this.Name = Name;
          this.isFolder = isFolder;
          Children = new List&lt;Project&gt;();
  
          if (ParentFolder == null)
          {
              Path = Name;
          }
          else
          {
              Path = ParentFolder.Path + " &gt; " + Name;
          }
      }
      public string Path { get; private set; }
      public string Name { get; set; }
      public bool isFolder { get; set; }
      public List&lt;Project&gt; Children { get; set; }
  
      public IEnumerable&lt;Project&gt; ChildFolders
      {
          get
          {
              return Children.Where(p =&gt; p.isFolder);
          }
      }
  
      public object Icon
      {
          get
          {
              if (isFolder)
              {
                  return 0; // return folder icon
              }
              else
              {
                  return 1; // return project icon
              }
          }
      }
  
      public IEnumerable&lt;Project&gt; SearchRecursively(string SearchString)
      {
          return GetAllChildren.Where(p =&gt; p.Name.Contains(SearchString));
      }
  
      private List&lt;Project&gt; GetAllChildren
      {
          get
          {
              List&lt;Project&gt; allChildren = new List&lt;Project&gt;();
              foreach(Project child in Children)
              {
                  allChildren.AddRange(child.GetAllChildren);
              }
              return allChildren;
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Here is my MaiWindow.xaml.cs class that I will be using to make test data:</p>
  
  <pre><code>    public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
              this.BuildData();
          }
  
          private void BuildData()
          {
             List&lt;Project&gt; parents = new List&lt;Project&gt;();
              Project parentOne = new Project("Apple", true, null);
              Project parentTwo = new Project("Samsung", true, null);
              Project parentThree = new Project("Google", true, null);
              parents.Add(parentOne); parents.Add(parentTwo); parents.Add(parentThree);
  
              Project appleMacBook = new Project("Mac", false, parentOne);
              Project appleIpad = new Project("iPad", false, parentOne);
              Project appleiPhone = new Project("iPhone", false, parentOne);
  
              Project samsungGalaxy = new Project("Galaxy", false, parentTwo);
              Project samsungNote = new Project("Note", false, parentTwo);
  
              Project googlePixel = new Project("Pixel", false, parentThree);
              Project googleChromecast = new Project("Chromecast", false, parentThree);
  
              parents[0].Children.Add(appleMacBook); parents[0].Children.Add(appleIpad); parents[0].Children.Add(appleiPhone);
              parents[1].Children.Add(samsungGalaxy); parents[1].Children.Add(samsungNote);
              parents[2].Children.Add(googlePixel); parents[2].Children.Add(googleChromecast); 
  
          }
      }
  }
  </code></pre>
  
  <p>And here is my XAML where I am trying to display the TreeView. Right now, it is just blank. I would appreciate any tips. </p>
  
  <pre><code>&lt;TreeView x:Name="Hierarchy" Grid.Column="4" HorizontalAlignment="Left" Height="631" Margin="0,58,0,0" Grid.Row="1" VerticalAlignment="Top" Width="265"
                ItemsSource="{Binding parents}"&gt;
          &lt;TreeView.ItemTemplate&gt;
              &lt;HierarchicalDataTemplate ItemsSource="{Binding parents}" DataType="{x:Type self:Project}"&gt;
                  &lt;TreeViewItem Header="{Binding Name}"&gt;&lt;/TreeViewItem&gt;
              &lt;/HierarchicalDataTemplate&gt;
          &lt;/TreeView.ItemTemplate&gt;
  </code></pre>
  
  <p>Edit:</p>
  
  <p>Here's the Property class:</p>
  
  <pre><code> public string Name
      {
          get
          {
              return name;
          }
          set
          {
              name = value;
              OnPropertyChanged("Name");
          }
      }
      private string name { get; set; }
      public event PropertyChangedEventHandler PropertyChanged;
  
      private void OnPropertyChanged(string propertyName)
      {
          if(PropertyChanged != null)
          {
              PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
      }
  </code></pre>
  
  <p>XAML:</p>
  
  <pre><code>&lt;TreeView.ItemTemplate&gt;
              &lt;HierarchicalDataTemplate ItemsSource="{Binding ChildFolders}"&gt;
                  &lt;StackPanel Orientation="Horizontal" &gt;
                      &lt;Image Source="{Binding Icon}" Margin="5, 5, 5, 5"&gt;&lt;/Image&gt;
                      &lt;TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" BorderThickness="0" FontSize="16" Margin="5"/&gt;
                  &lt;/StackPanel&gt;
              &lt;/HierarchicalDataTemplate&gt;
          &lt;/TreeView.ItemTemplate&gt;
      &lt;/TreeView&gt;
  </code></pre>
  
  <p>So, this doesn't seem to be firing the change event. I know this because Path is set as Name + ">". When I change the Name, Path is not reflecting the change. It only shows what my previous value for Name was, if that makes sense.</p>
  
  <pre><code>if (ParentFolder == null)
          {
              Path = Name;
          }
          else
          {
              Path = ParentFolder.Path + " &gt; " + Name;
          }
  </code></pre>
  
  <p>Edit:</p>
  
  <pre><code>public Project(string Name, bool isFolder, Project ParentFolder)
      {
          this.Name = Name;
          this.isFolder = isFolder;
          Children = new List&lt;Project&gt;();
          this.ParentFolder = ParentFolder;
      }
      public string Path
      {
          get
          {
              return this.ParentFolder + " &gt; " + this.Name;
          }
          set
          {
              this.Path = Path;
          }
      }
  </code></pre>
  
  <p>XAML: </p>
  
  <pre><code>&lt;TextBox x:Name="FolderNameBox" Grid.Column="1" Background="White" Grid.Row="1" Grid.ColumnSpan="5" 
                 Margin="0,0,287,654.333" VerticalContentAlignment="Center"
                 Padding="6" FontSize="16"
                 IsReadOnly="True"
                 Text="{Binding ElementName=Hierarchy, Path=SelectedItem.Path, UpdateSourceTrigger=PropertyChanged}"&gt;
      &lt;/TextBox&gt;
      &lt;TextBox x:Name="SearchProjectsBox" Grid.Column="5" Background="White" Grid.Row="1" Text="Search Projects" 
          Margin="47.333,0,0,654.333" VerticalContentAlignment="Center" Foreground="LightGray" Padding="6" FontSize="16" HorizontalAlignment="Left" Width="268" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus"/&gt;
      &lt;TreeView x:Name="Hierarchy" Grid.Column="4" HorizontalAlignment="Left" Height="631" Margin="0,58,0,0" Grid.Row="1" VerticalAlignment="Top" Width="226" 
                ItemsSource="{Binding Projects}"&gt;
  
          &lt;TreeView.ItemTemplate&gt;
              &lt;HierarchicalDataTemplate ItemsSource="{Binding ChildFolders}"&gt;
                  &lt;StackPanel Orientation="Horizontal" &gt;
                      &lt;Image Source="{Binding Icon}" Margin="5, 5, 5, 5"&gt;&lt;/Image&gt;
                      &lt;TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" BorderThickness="0" FontSize="16" Margin="5"/&gt;
                  &lt;/StackPanel&gt;
              &lt;/HierarchicalDataTemplate&gt;
          &lt;/TreeView.ItemTemplate&gt;
      &lt;/TreeView&gt;
      &lt;Grid Grid.ColumnSpan="2" Grid.Column="4" HorizontalAlignment="Left" Height="631" Margin="245,58,0,0" Grid.Row="1" VerticalAlignment="Top" Width="540"&gt;
          &lt;ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"&gt;
              &lt;ListView Margin="0,0,10,0" Name="ProjectView" ItemsSource="{Binding Projects}" FontSize="16" Foreground="Black"&gt;
                  &lt;ListView.View&gt;
                      &lt;GridView ColumnHeaderContainerStyle="{StaticResource GridHeader}"&gt;
                          &lt;GridViewColumn Header="Name" Width="200" DisplayMemberBinding="{Binding ElementName=Hierarchy, Path=SelectedItem.Name, UpdateSourceTrigger=PropertyChanged}"&gt;&lt;/GridViewColumn&gt;
                          &lt;GridViewColumn Header="Directory" Width="328" DisplayMemberBinding="{Binding ElementName=Hierarchy, Path=SelectedItem.Path, UpdateSourceTrigger=PropertyChanged}"&gt;&lt;/GridViewColumn&gt;
                      &lt;/GridView&gt;
                  &lt;/ListView.View&gt;
              &lt;/ListView&gt;
          &lt;/ScrollViewer&gt;
      &lt;/Grid&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p>The Path updates too but when it I see it it will display the path of the project rather than the fired change of name. It changes in real-time but doesn't save the String value..only registers that a change has happened. </p>
  
  <p>Heres my Property Change too. </p>
  
  <pre><code>public event PropertyChangedEventHandler PropertyChanged;
  
      private void OnPropertyChanged(string propertyName)
      {
          if(PropertyChanged != null)
          {
              PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
      }
  </code></pre>