WPF / XAML TreeView does not bind Hightlight nodes after binding

So I have a problem with TreeView. If I am an old static tree view, each node in the tree can be selected in the case when I click on it, it highlights the blue color, indicating that the node is selected.

<TreeView Grid.Column="0" Grid.Row="2" MinHeight="100" MinWidth="100" BorderBrush="White" DataContext="{Binding Projects, Source={x:Static SizingApp:Manager.Instance}}"> <TreeViewItem Header="Project 1" IsExpanded="True"> <TreeViewItem Header="Step 1" IsExpanded="True"> <TreeViewItem Header="Load 1" IsExpanded="True"></TreeViewItem> <TreeViewItem Header="Load 2" IsExpanded="True"></TreeViewItem> </TreeViewItem> <TreeViewItem Header="Step 2" IsExpanded="True"> <TreeViewItem Header="Load 1" IsExpanded="True"></TreeViewItem> <TreeViewItem Header="Load 2" IsExpanded="True"></TreeViewItem> </TreeViewItem> </TreeViewItem> 

However, I am attached to the TreeView to populate it. In addition, I am attached to objects that implement the Emiel Jongerius BindableObjectBase3 class . This is a great base class implementation that allows my objects to be Bindable and implement the INotifyPropertyChanged interface with the concern of manually managing DependencyProperty.

So this is the basic class structure (simplified from my real objects) that I am trying to implement in a TreeView.

  public abstract class MyCustomClass : BindableObjectBase3 { private string m_strName; public virtual string Name { get { using (this.GetPropertyTracker(() => this.Name)) { return m_strName; } } set { this.SetValue(ref this.m_strName, value, () => this.Name); } } } public class Project : MyCustomClass { private List<Step> m_steps; public List<Step> Steps { get { using (this.GetPropertyTracker(() => this.Steps)) { return m_steps; } } set { this.SetValue(ref this.m_steps, value, () => this.Steps); } } } public class Step : MyCustomClass { private List<Load> m_loads; public List<Load> Loads { get { using (this.GetPropertyTracker(() => this.Loads)) { return m_loads; } } set { this.SetValue(ref this.m_loads, value, () => this.Steps); } } } public class Load : MyCustomClass { } 

And this is the main XAML that I use to implement TreeView:

 <TreeView Grid.Column="0" Grid.Row="2" MinHeight="100" MinWidth="100" BorderBrush="White" DataContext="{Binding Projects, Source={x:Static SizingApp:Manager.Instance}}"> <TreeView.Resources> <HierarchicalDataTemplate x:Key="LoadTemplate"> <TreeViewItem Header="{Binding Path=Name}"> </TreeViewItem> </HierarchicalDataTemplate> <HierarchicalDataTemplate x:Key="StepTemplate"> <TreeViewItem Header="{Binding Path=Name}" IsExpanded="True" ItemsSource="{Binding Path=Loads}" ItemTemplate="{StaticResource LoadTemplate}"> </TreeViewItem> </HierarchicalDataTemplate> <HierarchicalDataTemplate x:Key="ProjectTemplate"> <TreeViewItem Header="{Binding Path=Name}" IsExpanded="True" ItemsSource="{Binding Path=Steps}" ItemTemplate="{StaticResource StepTemplate}"> </TreeViewItem> </HierarchicalDataTemplate> </TreeView.Resources> <TreeViewItem Header="{Resx ResxName=PSSPECApplication.Controls.ProjectControlResources, Key=projectTree_Header}" ItemsSource="{Binding}" IsExpanded="True" Focusable="True" ItemTemplate="{StaticResource ProjectTemplate}"> </TreeViewItem> </TreeView> 

Now all this works great if the binding is on. I can bind to an ObservableCollection <Project> and when I add / remove / manipulate projects, TreeView updates accordingly.

However, the only node in the TreeView that seems to be selected is the first node (the one that is static). All other nodes created using dynamic linking do not indicate that they are selected in the graphical interface. I would expect them to also highlight blue when pressed. But instead they do nothing. Does anyone have an idea of ​​why?

+3
source share
2 answers

You should not explicitly define TreeViewItems in your ItemTemplates. The reason you cannot select any item is because they do not have a parent TreeView to control the selection behavior. You must let TreeView generate the TreeViewItem controls for you and use the element templates to define the user interface for the headers and bindings for your elements. Instead, use something like this:

 <Window.Resources> <HierarchicalDataTemplate x:Key="LoadTemplate"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate x:Key="StepTemplate" ItemsSource="{Binding Loads}" ItemTemplate="{StaticResource LoadTemplate}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate x:Key="ProjectTemplate" ItemsSource="{Binding Steps}" ItemTemplate="{StaticResource StepTemplate}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> </Window.Resources> <TreeView MinHeight="100" MinWidth="100" BorderBrush="White" ItemsSource="{Binding Path=Projects}" ItemTemplate="{StaticResource ProjectTemplate}"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="True" /> </Style> </TreeView.ItemContainerStyle> </TreeView> 
+4
source

My TreeView acts just like the original poster described. I can select everything in my TreeView Control, but if I select a child, the parent Node will be what it selects, even if it binds and clicks on the child. I tried to structure my code to resemble John Bowen's suggestion and still get the same results. Here is my XAML code:

  <Fluent:RibbonWindow.Resources> <HierarchicalDataTemplate x:Key="MyTreeViewStyle" ItemsSource="{Binding Contacts}"> <!-- Display the Index by showing it Index string --> <StackPanel Orientation="Horizontal"> <Image x:Name="img" Width="16" Height="16" Stretch="Fill" Source="Images\closedfolder16.png" /> <TextBlock Text="{Binding Index}" Margin="5,0" ToolTip="{Binding Index}"/> </StackPanel> <HierarchicalDataTemplate.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image x:Name="img2" Width="16" Height="16" Stretch="Fill" Source="Images\closedfolder16.png" /> <TextBlock Text="{Binding Name}" Margin="5,0" ToolTip="{Binding Name}"/> </StackPanel> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> </HierarchicalDataTemplate> </Fluent:RibbonWindow.Resources> 

Then I use it here in my TreeView control:

  <Grid> <TreeView Margin="2,2,2,2" x:Name="MyTreeView" ItemTemplate="{StaticResource MyTreeViewStyle}" ItemContainerStyle="{StaticResource AlwaysExpand}" ScrollViewer.CanContentScroll="True" BorderThickness="0" TreeViewItem.Selected="btnDisplayContact_Click" /> </Grid> 

The result is a screenshot, pay attention to how the parent Node D is highlighted after clicking on the child node, and not the child Node is highlighted:

http://home.swbell.net/davis32/Snapshot.png

Cannot post images to just cut and paste the URL link.

+1
source

All Articles