C# 在IsSelected上的树视图中更改HeaderTemplate时,会为不同类型选择多个HierarchycalDataTemplates

C# 在IsSelected上的树视图中更改HeaderTemplate时,会为不同类型选择多个HierarchycalDataTemplates,c#,wpf,treeview,hierarchicaldatatemplate,C#,Wpf,Treeview,Hierarchicaldatatemplate,我有一个TreeView,我想向其中添加两种不同的节点类型,每种类型都有自己的HierachicalDataTemplate。我有这个工作(代码如下) 我想要的是,当选择树中的任何节点时,我希望该节点的模板发生更改,BoolNode节点使用不同的模板,CompareNode节点使用不同的模板。我发现了一些使用样式和触发器的示例,但它们都适用于树视图,其中所有节点共享相同的模板 TreeView Xaml: <TreeView Name="m_kTest"> &

我有一个
TreeView
,我想向其中添加两种不同的节点类型,每种类型都有自己的
HierachicalDataTemplate
。我有这个工作(代码如下)

我想要的是,当选择树中的任何节点时,我希望该节点的模板发生更改,BoolNode节点使用不同的模板,CompareNode节点使用不同的模板。我发现了一些使用样式和
触发器的示例,但它们都适用于
树视图,其中所有节点共享相同的模板

TreeView Xaml:

    <TreeView Name="m_kTest">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type self:BoolNode}" ItemsSource="{Binding Children}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding OpText}"/>
                </StackPanel>
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate DataType="{x:Type self:CompareNode}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Header}"/>
                    <TextBlock Text=" "/>
                    <TextBlock Text="{Binding OpText}"/>
                    <TextBlock Text=" "/>
                    <TextBlock Text="{Binding Value}"/>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>
    <TreeView Name="m_kTest">
        <TreeView.Resources>
            <HierarchicalDataTemplate x:Key="BoolDisplayTemplate" DataType="{x:Type self:BoolNode}" ItemsSource="{Binding Children}"> /*template*/ </HierarchicalDataTemplate>
            <HierarchicalDataTemplate x:Key="BoolEditTemplate" DataType="{x:Type self:BoolNode}" ItemsSource="{Binding Children}"> /*template*/ </HierarchicalDataTemplate>
            <HierarchicalDataTemplate x:Key="CompareEditTemplate"  DataType="{x:Type self:CompareNode}" ItemsSource="{Binding Children}"> /*template*/ </HierarchicalDataTemplate>
            <HierarchicalDataTemplate x:Key="CompareDisplayTemplate" DataType="{x:Type self:CompareNode}" ItemsSource="{Binding Children}"> /*template*/ </HierarchicalDataTemplate>

        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=IsBoolNode}" Value="True"/>
                        <Condition Binding="{Binding Path=IsSelected}" Value="False"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Value="{StaticResource BoolDisplayTemplate}" Property="HeaderTemplate"/>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=IsBoolNode}" Value="True"/>
                        <Condition Binding="{Binding Path=IsSelected}" Value="True"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Value="{StaticResource BoolEditTemplate}" Property="HeaderTemplate"/>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=IsBoolNode}" Value="False"/>
                        <Condition Binding="{Binding Path=IsSelected}" Value="False"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Value="{StaticResource CompareDisplayTemplate}" Property="HeaderTemplate"/>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding Path=IsBoolNode}" Value="False"/>
                        <Condition Binding="{Binding Path=IsSelected}" Value="True"/>
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter Value="{StaticResource CompareEditTemplate}" Property="HeaderTemplate"/>
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
        </TreeView.Resources>
    </TreeView>

IQueryNode:

public interface IQueryNode
{
    ObservableCollection<IQueryNode> Children { get; }
    int OpIndex { get; set; }
    String OpText{get;}
}
public interface IQueryNode
{
    ObservableCollection<IQueryNode> Children { get; }

    int OpIndex { get; set; }

    String OpText{get;}
    bool IsBoolNode { get; }
    bool IsSelected { get; set; }
}
公共接口IQueryNode
{
可观察收集子项{get;}
int OpIndex{get;set;}
字符串OpText{get;}
}
布尔节点:

public class BoolNode :IQueryNode
{
    public int OpIndex { get; set; }
    public String OpText { get { ... } }
    public ObservableCollection<IQueryNode> Children { get; private set; }

    public BoolNode()
    {
        Children = new ObservableCollection<IQueryNode>();
    }
}
public class BoolNode :IQueryNode
{
    public int OpIndex { get; set; }
    public String OpText { get { ... } }
    public ObservableCollection<IQueryNode> Children { get; private set; }
    public bool IsBoolNode{get{return true;}}
    public bool IsSelected { get; set;}

    public BoolNode()
    {
        OpIndex = 0;
        Children = new ObservableCollection<IQueryNode>();
        IsSelected = false;
    }
}
公共类BoolNode:IQueryNode
{
公共int OpIndex{get;set;}
公共字符串OpText{get{…}
公共可观测集合子项{get;private set;}
公共布尔节点()
{
Children=新的ObservableCollection();
}
}
比较节点:

public class CompareNode: IQueryNode
{
    public ObservableCollection<IQueryNode> Children { get; private set; }
    public int OpIndex { get; set; }
    public String OpText {get {...} }
    public String Header { get; set; }
    public String Value { get; set; }

    public CompareNode()
    {
        Children = new ObservableCollection<IQueryNode>();
    }
}
public class CompareNode: IQueryNode
{
    public ObservableCollection<IQueryNode> Children { get; private set; }
    public int OpIndex { get; set; }
    public String OpText{ get{ ... } }
    public String Header { get; set; }
    public String Value { get; set; }
    public bool IsBoolNode { get { return false; } }
    public bool IsSelected { get; set; }
    public CompareNode()
    {
        Children = new ObservableCollection<IQueryNode>();
        IsSelected = false;
    }
}
公共类比较节点:IQueryNode
{
公共可观测集合子项{get;private set;}
公共int OpIndex{get;set;}
公共字符串OpText{get{…}
公共字符串头{get;set;}
公共字符串值{get;set;}
公共比较节点()
{
Children=新的ObservableCollection();
}
}

这里有一种方法,我可以在选定的项目上获得自定义样式

XML:


C#:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
使用系统集合;
命名空间stackoverflowTreeview
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
数据=新列表()
{
新的Derp(“Derp根”,“Derp根值”)
{ 
Children=新列表()
{ 
新Herp(“Herp儿童”)
{ 
Children=new List(){new Derp(“Derp孙子”,“Derp孙子值”)}
},
新的Derp(“DERPChild2”、“DERPChild2值”)
{ 
Children=new List(){new Derp(“Derp孙子”,“Derp孙子值”)}
},
新Herp(“Herp儿童”)
{ 
Children=new List(){new Derp(“Derp孙子”,“Derp孙子值”)}
}
}
}
};
}
public static dependencProperty dData=dependencProperty.Register(“数据”、类型(列表)、类型(主窗口));
公共列表数据
{
获取{return(List)GetValue(dData);}
set{SetValue(dData,value);}
}
}
公共抽象类IHerp:DependencyObject
{
public static dependencProperty dChildren=dependencProperty.Register(“Children”、typeof(List)、typeof(ihrp));
公共列表子项{get{return(List)GetValue(dChildren);}set{SetValue(dChildren,value);}
public static dependencProperty dName=dependencProperty.Register(“名称”、typeof(字符串)、typeof(IHerp));
公共字符串名称{get{return(string)GetValue(dName);}set{SetValue(dName,value);}
公共IHerp()
{
Children=Children==null?新列表():Children;
Name=Name==null?“:Name;
}
}
公共舱Herp:IH
public class BoolNode :IQueryNode
{
    public int OpIndex { get; set; }
    public String OpText { get { ... } }
    public ObservableCollection<IQueryNode> Children { get; private set; }
    public bool IsBoolNode{get{return true;}}
    public bool IsSelected { get; set;}

    public BoolNode()
    {
        OpIndex = 0;
        Children = new ObservableCollection<IQueryNode>();
        IsSelected = false;
    }
}
public class CompareNode: IQueryNode
{
    public ObservableCollection<IQueryNode> Children { get; private set; }
    public int OpIndex { get; set; }
    public String OpText{ get{ ... } }
    public String Header { get; set; }
    public String Value { get; set; }
    public bool IsBoolNode { get { return false; } }
    public bool IsSelected { get; set; }
    public CompareNode()
    {
        Children = new ObservableCollection<IQueryNode>();
        IsSelected = false;
    }
}