在WPF中构建树形结构
- 首先构建一个属性结构的类,在这个类中,其中NodeId、NodeName、ParentId 是最重要的3个属性,是构建树形结构的关键.另外一个比较重要的属性就是ChildNodes,它是一个树形集合类对象,该属性存储子树,是构建树形结构的必要条件。其他都是附加属性,如Icon 用于存储图标,Tag用于扩展预留。
public class TTreeNode
{
public int NodeId { get; set; }
public int ParentId { get; set; }
public string NodeName { get; set; }
public string Icon { get; set; }
public string Tag { get; set; }
public List<TTreeNode> ChildNodes { get; set; }
public TTreeNode() {
ChildNodes = new List<TTreeNode>();
}
}
- 构建数据模型-视图模型
在数据模型类中定义了TreeNodes 属性,该属性用于存储树形结构节点数据。一个方法,通过递归方式遍历树形节点。
public class TreeViewModel:BasePropertyChanged
{
private List<TTreeNode> treenodes;
public List<TTreeNode> TreeNodes { get { return treenodes; }set { treenodes = value;RaiseProperty("TreeNodes"); } }
private List<TTreeNode> getChildNodes(int parentId, List<TTreeNode> nodes) {
List<TTreeNode> mainNodes = nodes.Where(x => x.ParentId == parentId).ToList();
List<TTreeNode> otherNodes = nodes.Where(x => x.ParentId != parentId).ToList();
foreach (TTreeNode node in mainNodes) {
node.ChildNodes = getChildNodes(node.NodeId, otherNodes);
}
return mainNodes;
}
public TreeViewModel(List<TTreeNode> nodes) {
TreeNodes = getChildNodes(0, nodes);
}
}
private ObservableCollection<TreeViewItemModel> deptItems { get; } = new ObservableCollection<TreeViewItemModel>();
private List<Permission> permissions;
private TreeViewModel tm;
private int pid;
private void DoSearch(int pId=1)
{
permissions = DbHelper.dbContext.permissions.ToList(); //获取数据
List<TTreeNode> nodes = new List<TTreeNode>(); //建立数据节点
foreach (var p in permissions) //填充数据
{
nodes.Add(new TTreeNode { NodeId = p.Id, ParentId = p.ParentId, NodeName = p.PerName, Icon = "\xe6d6", Tag = p.Id.ToString() });
}
TreeViewModel tv = new TreeViewModel(nodes); //构建树形结构数据模型对象
tvPermission.DataContext = tv;
}
<TreeView x:Name="tvPermission" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding TreeNodes}"
Margin="5,0,0,0"
Background="AliceBlue"
>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}"
BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="Visibility" Value="{Binding Visibility}" />
<Setter Property="IsExpanded" Value="true" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type m:TTreeNode}" ItemsSource="{Binding Path=ChildNodes}" >
<TextBlock>
<Run Text="{Binding Icon}" FontSize="17" FontFamily="{StaticResource iconfonts}"/> <Run Text="{Binding Path=NodeName}" />
</TextBlock>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
- 效果