Как использовать TreeView.Resources HierarchicalDataTemplate DataType, чтобы указать словарь<строка, список <T >>?
У меня есть список OBJs, которые я сохранил в 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>
Таким образом, в итоге у меня будет следующее:
- снаряды
- Снаряд А
- Снаряд Б
- Снаряд С
- Частицы
- Частица А
- Частица Б
- Частица С
Изменить: Это также должно работать, если у меня есть подуровни, см. Ниже.
- снаряды
- Снаряд СубТип А
- Снаряд А
- Снаряд SubType B
- Снаряд Б
- Снаряд С
- Снаряд СубТип А
- Частицы
- Частица А
- Частица Б
- Частица С
1 ответ
Попробуй это:
<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;