【WPF】树形结构TreeView的用法(MVVM)(转)

【WPF】树形结构TreeView的用法(MVVM)

 

TreeView控件的用法还是有蛮多坑点的,最好记录一下。

参考项目:


静态的树形结构

如果树形结构的所有子节点都已经确定且不会改动,可以直接在控制层用C#代码来生成这个TreeView。

复制代码
            var rootItem = new OutlineTreeData
            {
                outlineTypeName = "David Weatherbeam",
                Children=
                {
                    new OutlineTreeData
                    {
                        outlineTypeName="Alberto Weatherbeam",
                        Children=
                        {
                            new OutlineTreeData
                            {
                                outlineTypeName="Zena Hairmonger",
                                Children=
                                {
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Sarah Applifunk",
                                    }
                                }
                            },new OutlineTreeData
                            {
                                outlineTypeName="Jenny van Machoqueen",
                                Children=
                                {
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Nick van Machoqueen",
                                    },
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Matilda Porcupinicus",
                                    },
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Bronco van Machoqueen",
                                    }
                                }
                            }
                        }
                    },
                    new OutlineTreeData
                    {
                        outlineTypeName="Komrade Winkleford",
                        Children=
                        {
                            new OutlineTreeData
                            {
                                outlineTypeName="Maurice Winkleford",
                                Children=
                                {
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Divinity W. Llamafoot",
                                    }
                                }
                            },
                            new OutlineTreeData
                            {
                                outlineTypeName="Komrade Winkleford, Jr.",
                                Children=
                                {
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Saratoga Z. Crankentoe",
                                    },
                                    new OutlineTreeData
                                    {
                                        outlineTypeName="Excaliber Winkleford",
                                    }
                                }
                            }
                        }
                    }
                }
            };    
复制代码

运行后能看到树形结构是下面的样子。


获取TreeViewItem控件

前台页面xaml:

复制代码
 <!-- 树形结构 -->
 <TreeView x:Name="treeView" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,-10,0,0"
           ItemsSource="{Binding ItemTreeDataList}" BorderThickness="0" Width="215" Height="210">
     <TreeView.ItemContainerStyle>
         <Style TargetType="{x:Type TreeViewItem}">
             <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
             <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
             <Setter Property="FontWeight" Value="Normal" />
             <Style.Triggers>
                 <Trigger Property="IsSelected" Value="True">
                     <Setter Property="FontWeight" Value="Bold" />
                 </Trigger>
             </Style.Triggers>
         </Style>
     </TreeView.ItemContainerStyle>

     <TreeView.ItemTemplate>
         <HierarchicalDataTemplate ItemsSource="{Binding Children}">
             <TextBlock x:Name="treeViewItemTB" Text="{Binding itemName}" Tag="{Binding itemId}"/>
         </HierarchicalDataTemplate>
     </TreeView.ItemTemplate>
 </TreeView>  
复制代码

尝试过在初始化时获取TreeViewItem,发现都是为Null。

  • TreeViewItem item= (TreeViewItem)(myWindow.treeView.ItemContainerGenerator.ContainerFromIndex(0)); // 无法获取,为Null!
  • VisualTreeHelper.GetChild(); // 无法获取,为Null!

谷歌一下,看到这篇解答,下面这位跟我遇到的情况一样,用以上方法都无法获取TreeViewItem。

转载于:https://www.cnblogs.com/LiZhongZhongY/p/10883693.html

首先,我们需要在ViewModel中定义一个类来表示树节点,例如: ```csharp public class TreeNodeViewModel : INotifyPropertyChanged { private string _text; private ObservableCollection<TreeNodeViewModel> _children; public string Text { get { return _text; } set { if (_text != value) { _text = value; OnPropertyChanged(nameof(Text)); } } } public ObservableCollection<TreeNodeViewModel> Children { get { return _children; } set { if (_children != value) { _children = value; OnPropertyChanged(nameof(Children)); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` 然后,我们在MainViewModel中定义一个ObservableCollection<TreeNodeViewModel>来表示树的根节点,以及一些方法来添加/删除节点和处理双击事件: ```csharp public class MainViewModel : INotifyPropertyChanged { private ObservableCollection<TreeNodeViewModel> _rootNodes; public ObservableCollection<TreeNodeViewModel> RootNodes { get { return _rootNodes; } set { if (_rootNodes != value) { _rootNodes = value; OnPropertyChanged(nameof(RootNodes)); } } } public MainViewModel() { RootNodes = new ObservableCollection<TreeNodeViewModel>(); } public void AddNode(TreeNodeViewModel parent, string text) { if (parent == null) { RootNodes.Add(new TreeNodeViewModel { Text = text, Children = new ObservableCollection<TreeNodeViewModel>() }); } else { parent.Children.Add(new TreeNodeViewModel { Text = text, Children = new ObservableCollection<TreeNodeViewModel>() }); } } public void RemoveNode(TreeNodeViewModel node) { if (node == null) { return; } if (node == RootNodes.FirstOrDefault()) { RootNodes.Remove(node); } else { var parent = FindParentNode(RootNodes, node); if (parent != null) { parent.Children.Remove(node); } } } public void HandleDoubleClick(TreeNodeViewModel node) { // handle double click event } private TreeNodeViewModel FindParentNode(IEnumerable<TreeNodeViewModel> nodes, TreeNodeViewModel child) { foreach (var node in nodes) { if (node == child || node.Children == null) { continue; } if (node.Children.Contains(child)) { return node; } var parent = FindParentNode(node.Children, child); if (parent != null) { return parent; } } return null; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` 最后,我们可以在View中使用TreeView控件来显示树,并将其绑定到MainViewModel中的RootNodes属性。我们还可以为TreeViewItem添加双击事件处理程序,以及为ContextMenu添加添加/删除节点的菜单项。 ```xaml <TreeView ItemsSource="{Binding RootNodes}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Children}"> <TextBlock Text="{Binding Text}" /> </HierarchicalDataTemplate> </TreeView.ItemTemplate> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="TreeViewItem_DoubleClick" /> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="Add Node" Command="{Binding AddNodeCommand}" /> <MenuItem Header="Remove Node" Command="{Binding RemoveNodeCommand}" /> </ContextMenu> </Setter.Value> </Setter> </Style> </TreeView.ItemContainerStyle> </TreeView> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值