我有以下课程:
class Component
{
ComponentType ComponentType {get; set;}
string Name {set; set;}
List<Component> SubComponents {get; set;}
}
enum ComponentType
{
Feature,
Role
}
在我的VM上,一个List<Component> AllComponents {get;}
包含我所有组件的所有,而与ComponentType
无关。
我希望不必Component
分隔ComponentType
,而是将它们显示在TreeView
中,如下所示:
Roles
ComponentA
ComponentB
ComponentC
ComponentD
ComponentE
Features
ComponentF
ComponentG
ComponentH
ComponentI
但是我真的不确定如何在WPF中执行此操作而不必创建两个单独的List<Component>
或Dictionary<ComponentType, Component>
(我也想避免)。
一个非常简单的问题,有没有办法仅使用XAML来实现这一目标?
PS:所有SubComponents
都将始终与其父母拥有相同的ComponentType
。
答案 0 :(得分:0)
AllComponens
应该包含两个分层的Component
对象-名称“ Roles”和“ Features”-代表每棵树的根。
然后,“ Roles”对象的SubComponents
属性应包含其他三个Component
对象(ComponentA,B和E),而“ Features”对象的SubComponents
属性还应包含三个子对象对象(F,G和I),例如:
public List<Component> AllComponents { get; } = new List<Component>()
{
new Component(){ Name = "Roles", SubComponents = new List<Component>(){ new Component() { Name = "A" }, new Component() { Name = "B" }, new Component() { Name = "E" } } },
new Component(){ Name = "Features",SubComponents = new List<Component>(){ new Component() { Name = "F" }, new Component() { Name = "G" }, new Component() { Name = "I" } } }
};
如果在视图模型中像这样组织数据,则可以使用以下TreeView表示层次结构:
<TreeView ItemsSource="{Binding AllComponents}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubComponents}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
答案 1 :(得分:0)
您可以使用CollectionViewSource
(Details),它支持按给定Property
的Collection-Item进行分组。
以下是XAML中的一个示例:
<Grid>
<!-- Define CollectionViewSource (must be declared as static resource) -->
<Grid.Resources>
<!-- Bind to Components List and add key 'ComponentTypeGrouper' -->
<CollectionViewSource x:Key="ComponentTypeGrouper" Source="{Binding AllComponents}">
<!-- Group by the Property 'ComponentType' -->
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ComponentType" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Grid.Resources>
<!-- Set source of TreeView to the 'ComponentGrouper' -->
<TreeView ItemsSource="{Binding Source={StaticResource ComponentTypeGrouper}}">
<!-- Hierarchical Template to support nested Components -->
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubComponents}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<!-- Group Container Style (how Roles/Features are displayed) -->
<TreeView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<!-- Name of the Groups (expandable as treeviewitem) -->
<TreeViewItem Header="{Binding Name}">
<ItemsPresenter/>
</TreeViewItem>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</TreeView.GroupStyle>
</TreeView>
</Grid>
答案 2 :(得分:0)
我已经使用TreeviewItemModel做到了这一点:
public class TreeViewItemViewModel : BindableBase
{
private string _name;
private TreeViewItemViewModel _parent;
private List<TreeViewItemViewModel> _childern;
public TreeViewItemViewModel(TreeViewItemViewModel parent, string name)
{
_parent = parent;
_name = name;
_childern = new List<TreeViewItemViewModel>();
}
public string Name
{
get
{
return _name;
}
}
public TreeViewItemViewModel Parent
{
get
{
return _parent;
}
}
public List<TreeViewItemViewModel> Children
{
get
{
return _childern;
}
}
public void AddChild(TreeViewItemViewModel c)
{
_childern.Add(c);
RaisePropertyChanged(nameof(Children));
}
}
那么您只需要:
<TreeView Grid.Row="1" Grid.Column="0" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
ItemsSource="{Binding TreeItemsUserSearch}"
IsEnabled="{Binding TreeEnabled}">
<i:Interaction.Behaviors>
<b:TreeViewSelectedItemBehavior SelectedItem="{Binding SelectedTreeItemUserSearch}" />
</i:Interaction.Behaviors>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
在ViewModel中,您只需要具备以下条件:
private List<TreeViewItemViewModel> _treeItemsUserSearch;
public List<TreeViewItemViewModel> TreeItemsUserSearch
{
get
{
return _treeItemsUserSearch;
}
}
然后您可以创建所需的每种结构