WPF中具有多个叶数据类型的TreeView
本文关键字:数据类型 TreeView WPF | 更新日期: 2023-09-27 18:29:36
我正在尝试创建一个具有以下层次结构的TreeView:
Device1
--File1
--File2
--Hook1
--Hook2
Device2
--File1
--File1
Device3
--Hook1
所以基本上根级节点是一个设备,其子节点是File和Hook。我用分层数据模板创建了以下树
<TreeView ItemsSource="{Binding Devices}">
<HierarchicalDataTemplate DataType="{x:Type datamodel:Device}" ItemsSource="{Binding Files}">
<TextBlock Margin="5,5,0,0" Text="{Binding DeviceName}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate DataType="{x:Type datamodel:File}">
<TextBlock Margin="5,0,0,0" Text="{Binding FileName}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
Class Devices
{
public string DeviceName
{
get;set;
}
public string List<File> Files
{
get;set;
}
public string List<Hook> Hooks
{
get;set;
}
}
public class File
{
public string FileName
{
get;set;
}
public string FileType
{
get;set;
}
public string Location
{
get; set;
}
}
public class Hook
{
public string HookName
{
get;set;
}
public string Type
{
get;set;
}
}
我只能在层次结构数据模板的ItemTemplate中添加一个数据模板。如何在一个层次结构数据模板下指定两种数据类型??
您必须在此处使用转换器,它将返回包含文件和挂钩的CompositeCollection
。您将使用此转换器与HierarchicalDataTemplate DataType="{x:Type datamodel:Device}"
的ItemsSource
然后,您只需要为File和Hook数据类型定义两个数据模板。
感谢
我尝试了CompositeCollection,但意识到绑定对象已转换为基类型。所以我将它与DataTemplateSelector结合使用。以下解决方案对我有效。
<TreeView ItemsSource="{Binding Devices}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type datamodel:Devices}" ItemTemplateSelector="{StaticResource LeafDataTemplateSelector}">
<HierarchicalDataTemplate.ItemsSource>
<MultiBinding Converter="{StaticResource CompositeCollectionConverter}">
<Binding Path="Files" />
<Binding Path="Hooks"/>
</MultiBinding>
</HierarchicalDataTemplate.ItemsSource>
<StackPanel Height="25" Orientation="Horizontal">
<Image Height="20" Width="20" Source="Device.png"/>
<TextBlock Margin="5,5,0,0" Text="{Binding Device}"/>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate x:Key="FileKey" DataType="{x:Type datamodel:File}">
<StackPanel Height="25" Orientation="Horizontal" ToolTip="Installation File">
<Image Height="20" Width="20" Source="File.png" />
<TextBlock Text="{Binding FileName}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="HookKey" DataType="{x:Type datamodel:Hook}">
<StackPanel Height="25" Orientation="Horizontal" ToolTip="Installation Hook">
<Image Height="20" Width="20" Source="Hook.png" />
<TextBlock Margin="5,5,0,0" Text="{Binding HookName}"/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
已使用模板选择器根据键选择适当的模板。
public class LeafDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null)
{
if (item is InstallationManifesFile)
return
element.FindResource("FileKey")
as DataTemplate;
else if (item is InstallationManifestHook)
return element.FindResource("HookKey")
as DataTemplate;
}
return null;
}
}
public class CompositeCollectionConverter : IMultiValueConverter
{
public object Convert(object[] values
, Type targetType
, object parameter
, System.Globalization.CultureInfo culture)
{
var res = new CompositeCollection();
foreach (var item in values)
if (item is IEnumerable && item != null)
res.Add(new CollectionContainer()
{
Collection = item as IEnumerable
});
return res;
}
public object[] ConvertBack(object value
, Type[] targetTypes
, object parameter
, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}