一个模板用于多个类似的 HierarchicalDataTemplate-s?
One template for multiple similar HierarchicalDataTemplate-s?
我有一个 TreeView 组件,它可以包含多种类型的节点。它一切正常,除了我有多个分层数据模板,它们仅在它们显示的字形图像、DataType 和 ItemsSource 上有所不同,但其他一切都完全相同。
我想知道,是否可以为所有分层数据模板创建一个 ControlTemplate,并使用标签 属性 修改图标图像?
例如,我有基本的 TreeNode class 和继承自 TreeNode 的节点,如 PersonNode、PropertyNode、StreetNode。 TreeNode 显示文件夹图标,PersonNode 显示用户图标,PropertyNode 显示房屋图标,StreeNode 显示街道图标。
所以,实际上它们都具有相同的内容结构,只是图标、DataType 和 ItemsSource 正在改变。
如何简化分层数据模板?
示例代码:
<HierarchicalDataTemplate
DataType="{x:Type MyTreeFolder:TreeNode}"
ItemsSource="{Binding Path=Items}">
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSpecialNode}" Value="True">
<Setter Property="Background" Value="Blue"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<glyphs:GlyphAwesome
FontSize="12"
Glyph="folder"
Margin="0, 0, 4, 0"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</StackPanel>
</HierarchicalDataTemplate>
您可以创建一个值转换器来检查树节点的类型和 returns 字形文本。字形文本映射的类型可以存储在字典中。
public class ObjectTypeToGlyphConverter : IValueConverter
{
private static readonly IDictionary<Type, string> TypeToGlyphMapping = new Dictionary<Type, string>
{
[typeof(TreeNode)] = "folder",
[typeof(PersonNode)] = "person",
[typeof(PropertyNode)] = "property"
};
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var type = value?.GetType();
return type != null && TypeToGlyphMapping.TryGetValue(type, out var glyph) ? glyph : null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
您需要在范围内的资源字典中创建此转换器的实例,例如:
<TreeView ItemsSource="{Binding TreeNodes}">
<TreeView.Resources>
<local:ObjectTypeToGlyphConverter x:Key="ObjectTypeToGlyphConverter"/>
</TreeView.Resources>
<!-- ...tree view definitions. -->
</TreeView>
然后您可以像这样在分层数据模板的 GlyphAwesome
中使用它。
<glyphs:GlyphAwesome FontSize="12"
Glyph="{Binding Converter={StaticResource ObjectTypeToGlyphConverter}}"
Margin="0, 0, 4, 0"
VerticalAlignment="Center"/>
在这种情况下,您只需要一个类型 TreeNode
的数据模板,因为正如您所说,所有节点类型本质上都是相同的,除了图标之外没有对它们进行特殊处理。
我有一个 TreeView 组件,它可以包含多种类型的节点。它一切正常,除了我有多个分层数据模板,它们仅在它们显示的字形图像、DataType 和 ItemsSource 上有所不同,但其他一切都完全相同。
我想知道,是否可以为所有分层数据模板创建一个 ControlTemplate,并使用标签 属性 修改图标图像?
例如,我有基本的 TreeNode class 和继承自 TreeNode 的节点,如 PersonNode、PropertyNode、StreetNode。 TreeNode 显示文件夹图标,PersonNode 显示用户图标,PropertyNode 显示房屋图标,StreeNode 显示街道图标。 所以,实际上它们都具有相同的内容结构,只是图标、DataType 和 ItemsSource 正在改变。
如何简化分层数据模板?
示例代码:
<HierarchicalDataTemplate
DataType="{x:Type MyTreeFolder:TreeNode}"
ItemsSource="{Binding Path=Items}">
<StackPanel Orientation="Horizontal">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSpecialNode}" Value="True">
<Setter Property="Background" Value="Blue"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<glyphs:GlyphAwesome
FontSize="12"
Glyph="folder"
Margin="0, 0, 4, 0"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</StackPanel>
</HierarchicalDataTemplate>
您可以创建一个值转换器来检查树节点的类型和 returns 字形文本。字形文本映射的类型可以存储在字典中。
public class ObjectTypeToGlyphConverter : IValueConverter
{
private static readonly IDictionary<Type, string> TypeToGlyphMapping = new Dictionary<Type, string>
{
[typeof(TreeNode)] = "folder",
[typeof(PersonNode)] = "person",
[typeof(PropertyNode)] = "property"
};
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var type = value?.GetType();
return type != null && TypeToGlyphMapping.TryGetValue(type, out var glyph) ? glyph : null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
您需要在范围内的资源字典中创建此转换器的实例,例如:
<TreeView ItemsSource="{Binding TreeNodes}">
<TreeView.Resources>
<local:ObjectTypeToGlyphConverter x:Key="ObjectTypeToGlyphConverter"/>
</TreeView.Resources>
<!-- ...tree view definitions. -->
</TreeView>
然后您可以像这样在分层数据模板的 GlyphAwesome
中使用它。
<glyphs:GlyphAwesome FontSize="12"
Glyph="{Binding Converter={StaticResource ObjectTypeToGlyphConverter}}"
Margin="0, 0, 4, 0"
VerticalAlignment="Center"/>
在这种情况下,您只需要一个类型 TreeNode
的数据模板,因为正如您所说,所有节点类型本质上都是相同的,除了图标之外没有对它们进行特殊处理。