我有一个OBJ列表,我已经存储到List<OBJ> OBJS
属性中,我为数据创建了一个HierarchicalDataTemplate
,它可以工作(见下文)。
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type EntityType:Projectiles}"
ItemsSource="{Binding Value}">
<TextBlock Text="{Binding RelativeSource={RelativeSource Self},
Converter={StaticResource NameConverter}}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
这给了我下面的TreeView:
但是,因为我的数据实际上是List
OBJ
,所以有同一列表中的子类,我想将这些类分组在自己的Type
下。即new List<OBJ>() { new Projectiles(), new Particles() }
应该有Projectiles
,Particles
等的节点。我创建了Converter
,将其更改为Dictionary
,然后它不适用于上述HierarchicalDataTemplate
,因为它现在是Dictionary<string, List<OBJ>
。
然后我创建了一个处理HierarchicalDataTemplate
的新Dictionary<string, List<OBJ>
,见下文。
<TreeView Name="MyTreeView" ItemsSource="{Binding OBJS,
Converter={StaticResource ItemsSourceConverter}}"
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Value}">
<TextBlock Text="{Binding Key}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
Converter
:
class ItemsSourceConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
List<OBJ> objs = new List<OBJ>(value as List<OBJ>);
var query = (from a in objs
group a by a.GetType() into b
select new {
EntityName = b.Key.ToString().Split('.').Last().Substring(0,1).ToUpper() + b.Key.ToString().Split('.').Last().Substring(1).ToLower(),
Entities = b.OrderBy(a=>a.retrieveName()).ToList()
}).ToDictionary(kvp => kvp.EntityName, kvp => kvp.Entities);
return query;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
return null;
}
}
这给了我下面的TreeView,创建了正确的组:
但扩展它们会为Particles
或Projectiles
中的每个节点带来以下两个错误。
System.Windows.Data Error: 40 : BindingExpression path error: 'Value' property not found on 'object' 'Projectiles' (HashCode=37857370)'. BindingExpression:Path=Value; DataItem='Projectiles' (HashCode=37857370); target element is 'TreeViewItem' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Error: 40 : BindingExpression path error: 'Key' property not found on 'object' 'Projectiles' (HashCode=37857370)'. BindingExpression:Path=Key; DataItem='Projectiles' (HashCode=37857370); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
似乎一旦设置TreeView.ItemTemplate
,它就会忽略您在DataTemplates
中定义的所有TreeView.Resources
?
在我的第一次尝试中,我能够使用DataType="{x:Type EntityType:Projectiles}"
指定我希望HierarchicalDataTemplate
用于Projectiles
个对象,是否有DataType
语法我会指定DataType="{x:Type Dictionary<string, List<OBJ>>}"
吗?所以我可以做类似下面的事情?
<HierarchicalDataTemplate ItemsSource="{Binding Value}"
DataType="{x:Type Dictionary<string, List<OBJ>>}">
<TextBlock Text="{Binding Key}" />
</HierarchicalDataTemplate>
那样,最后,我会得到以下内容:
编辑:如果我有子级别,这也应该有效,见下文。
答案 0 :(得分:0)
试试这个:
<TreeView Name="treeView1" ItemsSource="{Binding}" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Value}">
<TextBlock FontWeight="Bold" Text="{Binding Path=Key}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
示例类:
class OBJ
{
public string Name { get; set; }
}
class Projectiles : OBJ {}
class Particles : OBJ {}
示例数据初始化:
List<OBJ> _source = new List<OBJ>()
{
new Projectiles{ Name = "Projectile A"},
new Projectiles{ Name = "Projectile B"},
new Projectiles{ Name = "Projectile C"},
new Particles { Name = "Particle A"},
new Particles { Name = "Particle B"},
new Particles { Name = "Particle C"},
};
var query = (from a in _source
group a by a.GetType() into b
select new
{
EntityName = b.Key.ToString().Split('.').Last().Substring(0, 1).ToUpper() + b.Key.ToString().Split('.').Last().Substring(1).ToLower(),
Entities = b.OrderBy(a => a.Name).ToList()
}).ToDictionary(kvp => kvp.EntityName, kvp => kvp.Entities);
treeView1.DataContext = query;