开发者

WPF/XAML TreeView doesn't Hightlight Nodes after Binding

So I am having an issue with the TreeView. If I build a tree view statically, every node in the tree is selectable in that when I click on it, it highlights itself blue, indicating that 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 Binding to the TreeView to populate it. Furthermore, I am binding to objects that implement Emiel Jongerius's BindableObjectBase3 class. This is a wonderful base class implementation that allows my objects to be Bindable and implement the INotifyPropertyChanged interface with the concern for manual DependencyProperty management.

So this is the basic class structure (simplified from my actual 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;
开发者_如何学Python
    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 basic XAML I use to implement the 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 of this works fine as far as binding goes. I can bind to an ObservableCollection<Project> and as I add/remove/manipulate projects, the TreeView updates accordingly.

However, the only node in the TreeView that seems selectable is the first node (the one that is static). All of the other nodes create through dynamic Binding do not indicate that they are selected on the GUI. I would expect that they would also highlight blue when clicked on. But instead they do nothing. Does anyone have an idea of why?


You shouldn't be defining TreeViewItems explicitly in your ItemTemplates. The reason you can't select any of the items is that they have no parent TreeView to control selection behavior. You need to let the TreeView generate the TreeViewItem controls for you and only use the item templates to define the UI for the Headers and the bindings for their items. Use something like this instead:

<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>


My TreeView is acting just as the original poster has described. I'm able to select everything in my TreeView Control but If I select a childnode the Parent Node is what Highlights even though It binds and clicks the child. I tried structuring 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's 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 this screenshot, notice how the parent node D is highlighted after clicking the child node, instead of the child node being highlighted:

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

Can't post images so just cut and paste the URL link.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜