如何更改 HierarchicalDataTemplate?
How to change HierarchicalDataTemplate?
如何在我的 TreeView 中通过 DataTrigger 更改 HierarchicalDataTemplate?
<TreeView Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding Nodes}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="group">
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="{Binding Title}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="page">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Page.Name}" />
<TextBlock Text="{Binding Page.Format}" />
</StackPanel>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
在 TreeView 的 ItemSource 中,我放置了节点对象列表:
public class Node
{
public string Title { get; set; }
public Page Page { get; set; }
public string Type { get; set; }
public List<Node> Nodes { get; set; } = new List<Node>();
}
这是结果:
我做错了什么?
在 WPF 中,"correct" 创建复杂内容的方法是使用模板。
我尝试了下面的 XAML,它起作用了。我在内部 ContentControl
上绑定 Content="{Binding}"
,这只是将 contentcontrol 的内容绑定到父对象的 DataContext
—— 在本例中,是 Node
对象。
您也可以通过编写两个完整的 HierarchicalDataTemplates and a DataTemplateSelector 在它们之间进行选择来做到这一点。这将是一种更正统的 WPF 方法,但这是纯粹的 XAML 并且非常简单。
<TreeView
Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding Nodes}"
>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
<ContentControl
x:Name="PART_ContentControl"
Content="{Binding}"
/>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="Group">
<Setter Property="ContentTemplate" TargetName="PART_ContentControl">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="Page">
<Setter Property="ContentTemplate" TargetName="PART_ContentControl">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Page.Name}" />
<TextBlock Text="{Binding Page.Format}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
您会注意到 Type
的触发值在我的标记中大写。我用枚举替换了你的字符串,以避免可能的错误来源:
public enum NodeType {
Page, Group
}
public class Node
{
public string Title { get; set; }
public Page Page { get; set; }
public NodeType Type { get; set; }
public List<Node> Nodes { get; set; } = new List<Node>();
}
如何在我的 TreeView 中通过 DataTrigger 更改 HierarchicalDataTemplate?
<TreeView Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding Nodes}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="group">
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="{Binding Title}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="page">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Page.Name}" />
<TextBlock Text="{Binding Page.Format}" />
</StackPanel>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
在 TreeView 的 ItemSource 中,我放置了节点对象列表:
public class Node
{
public string Title { get; set; }
public Page Page { get; set; }
public string Type { get; set; }
public List<Node> Nodes { get; set; } = new List<Node>();
}
这是结果:
我做错了什么?
在 WPF 中,"correct" 创建复杂内容的方法是使用模板。
我尝试了下面的 XAML,它起作用了。我在内部 ContentControl
上绑定 Content="{Binding}"
,这只是将 contentcontrol 的内容绑定到父对象的 DataContext
—— 在本例中,是 Node
对象。
您也可以通过编写两个完整的 HierarchicalDataTemplates and a DataTemplateSelector 在它们之间进行选择来做到这一点。这将是一种更正统的 WPF 方法,但这是纯粹的 XAML 并且非常简单。
<TreeView
Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding Nodes}"
>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
<ContentControl
x:Name="PART_ContentControl"
Content="{Binding}"
/>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="Group">
<Setter Property="ContentTemplate" TargetName="PART_ContentControl">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="Page">
<Setter Property="ContentTemplate" TargetName="PART_ContentControl">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Page.Name}" />
<TextBlock Text="{Binding Page.Format}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
您会注意到 Type
的触发值在我的标记中大写。我用枚举替换了你的字符串,以避免可能的错误来源:
public enum NodeType {
Page, Group
}
public class Node
{
public string Title { get; set; }
public Page Page { get; set; }
public NodeType Type { get; set; }
public List<Node> Nodes { get; set; } = new List<Node>();
}