I got this to work in a sort of "hacky" way.
I added a "IsSelected" property to my two classes and bound it to the IsSelected property of the TreeViewNode. Then, since I only had two data types I was working with, I added a "IsBoolean" boolean field and triggered the template change on those two values:
TreeView Xaml:
<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;}
bool IsBoolNode { get; }
bool IsSelected { get; set; }
}
BoolNode:
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;
}
}
CompareNode:
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;
}
}