WPF Treeview 学习 增加图标、checkbox和右键菜单(转载)

最近在学习wpf,习惯把自己学习的东西记下来。

  刚开始接触的这个控件,有点不知道怎么用。网上看了下,好像大家都觉得不如winform里面的好使。反正,我以前是用mfc做界面的,对c#不熟。网上看了几个例子,自己动手做了一下,现在把大概步骤记录下来。我这里比较简单,没有用什么模式。网上有一篇《使用ViewModel模式来简化WPF的TreeView》大家可以看看。

  一、一个简单的树

  首先、定义一个树节点的类,用来保存树节点信息:

  TreeItem.cs文件:

   using System;

   using System.Collections.Generic;

   using System.Linq;

   using System.Text;

   using System.Collections.ObjectModel;

   namespace WPFTreeviewExamples

  {

   class TreeItem

  {

   // 构造函数

   public TreeItem()

  {

  children=  new ObservableCollection();

  }

   //

   // 节点文字信息

   public stringtext

  {

   get;

   set;

  }

   // 节点其他信息

   // ...

   // 父节点

   public TreeItemparent

  {

   get;

   set;

  }

   // 子节点

   public ObservableCollection children

  {

   get;

   set;

  }

   //

  }

  }

  然后、在xaml文件中定义树的属性样式:

< TreeView Name= "treeViewSimple"  >

            < TreeView.ItemContainerStyle>

                < Style TargetType= "{x:TypeTreeViewItem}">

                    < Setter Property= "IsExpanded"  Value= "true" />

                < /Style>

            < /TreeView.ItemContainerStyle>

            < TreeView.Resources>

                < HierarchicalDataTemplate DataType= "{x:Type local:TreeItem}"   ItemsSource= "{Binding Path=children}">

                    < StackPanel Orientation= "Horizontal"  Margin= "0,2,0,2">                       

                        < TextBlock Text= "{Binding text}"  ToolTip= "{Binding text}" />

                    < /StackPanel>

                < /HierarchicalDataTemplate>                

            < /TreeView.Resources>

        < /TreeView>

  其中:<Setter Property="IsExpanded" Value="true"/>表示所有节点都展开。

  HierarchicalDataTemplate定义节点样式。DataType="{x:Typelocal:TreeItem}用来表明存储节点数据的类是什么。

  二、带图标的树

  很简单,只要添加图标相关信息即可:

  TreeItem.cs文件:

//

        // 节点文字信息

        public stringtext

       {

             get;

             set;

       }

        // 节点图标路径

        public stringitemIcon

       {

             get;

             set;

       }

        // 节点其他信息

         // ...

  xaml文件

< TreeView.Resources>

                < HierarchicalDataTemplate DataType= "{x:Type local:TreeItem}"   ItemsSource= "{Binding Path=children}">

                    < StackPanel Orientation= "Horizontal"  Margin= "0,2,0,2">  

                        < Image VerticalAlignment= "Center"  Source= "{Binding itemIcon}"  >< /Image>

                        < TextBlock VerticalAlignment= "Center"  Text= "{Binding text}"  ToolTip= "{Binding text}" />

                    < /StackPanel>

                < /HierarchicalDataTemplate>                

            < /TreeView.Resources>

  三、更多功能的树

  1、 首先,让我加一个checkbox

  这需要完善 TreeItem:

  让它继承与INotifyPropertyChanged 接口,以便通知checkbox状态改变:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Collections.ObjectModel;

using System.ComponentModel;

namespace WPFTreeviewExamples

{

    class TreeItem: INotifyPropertyChanged

   {

        // 构造函数

        public TreeItem()

       {

            children=  new ObservableCollection<TreeItem>();

       }
        //

        // 节点文字信息

        public stringtext

       {

             get;

             set;

       }

        // 节点图标路径

        public stringitemIcon

       {

             get;

             set;

       }

        // 节点其他信息

        // ...
        // 父节点

        public TreeItemparent

       {

             get;

             set;

       }

        // 子节点

        public ObservableCollection<TreeItem> children

       {

             get;

             set;

       }

        //
           Check 相关信息  ///

        bool? _isChecked=  false;
        public  bool?IsChecked

       {

             getreturn _isChecked;}

             setthis.SetIsChecked( valuetruetrue); }

       }
        void SetIsChecked( boolvaluebool updateChildren, bool updateParent)

       {

             if( value == _isChecked)

                 return;

             _isChecked=  value;

              if(updateChildren && _isChecked.HasValue)

            {

                 foreach(TreeItem childin children)

                {

                    child.SetIsChecked(_isChecked, truefalse);

                }

            }

              if(updateParent && parent !=  null)

            {

                parent.VerifyCheckState();

            }

              this.OnPropertyChanged( "IsChecked");

       }

        void VerifyCheckState()

       {

             bool?state =  null;

             for( int i = 0; i <  this.children.Count;++i)

            {

                 bool? current =  this.children[i].IsChecked;

                 if(i == 0)

                {

                    state= current;

                }

                elseif (state !=current)

                {

                    state=  null;

                     break;

                }

            }

             this.SetIsChecked(state, falsetrue);

       }

       

        void OnPropertyChanged( string prop)

       {

             if( this.PropertyChanged!=  null)

                 this.PropertyChanged( this, new PropertyChangedEventArgs(prop));

       }

 

        public eventPropertyChangedEventHandler PropertyChanged; 

        //

   }

}
< TreeView.Resources>

                < HierarchicalDataTemplate DataType= "{x:Type local:TreeItem}"   ItemsSource= "{Binding Path=children}">

                    < StackPanel Orientation= "Horizontal"  Margin= "0,2,0,2">  

                        < CheckBox Focusable= "False"  IsChecked= "{Binding IsChecked,Mode=TwoWay}" VerticalAlignment= "Center"  />

                        < Image VerticalAlignment= "Center"  Source= "{Binding itemIcon}"  >< /Image>

                        < TextBlock VerticalAlignment= "Center"  Text= "{Binding text}"  ToolTip= "{Binding text}" />

                    < /StackPanel>

                < /HierarchicalDataTemplate>                

            < /TreeView.Resources>
   void InitTree()

  {

  tree=  new TreeItem();

   // 添加一级顶层子节点

  TreeItemroot =  new TreeItem();

  root.text =  "根节点";

  root.itemIcon =  "./image/root.png";

   // 把根节点加进来

  tree.children.Add(root);

  root.parent = tree;

   // 给根节点加一些子节点

  TreeItemhubei =  new TreeItem();

  hubei.text =  "湖北";

  hubei.itemIcon =  "./image/Provine.png";

  root.children.Add(hubei);

  hubei.parent = root;

   // 给湖北下加几个城市

  TreeItemwuhan =  new TreeItem();

  wuhan.text =  "武汉";

  wuhan.itemIcon =  "./image/City.png";

  TreeItemxiaogan = newTreeItem();

  xiaogan.text =  "孝感";

  xiaogan.itemIcon =  "./image/City.png";

  TreeItemxiangyang = newTreeItem();

  xiangyang.text =  "襄阳";

  xiangyang.itemIcon =  "./image/City.png";

  hubei.children.Add(wuhan);

  wuhan.parent = hubei;

  hubei.children.Add(xiaogan);

  xiaogan.parent = hubei;

  hubei.children.Add(xiangyang);

  xiangyang.parent = hubei;

   // 给根节点加一些子节点

  TreeItemfamily = newTreeItem();

  family.text =  "我的家";

  family.itemIcon =  "./image/Provine.png";

  root.children.Add(family);

  family.parent = root;

   // 给湖北下加几个城市

  TreeItemdad =  new TreeItem();

  dad.text =  "爸爸";

  dad.itemIcon =  "./image/City.png";

  TreeItemmom =  new TreeItem();

  mom.text =  "妈妈";

  mom.itemIcon =  "./image/City.png";

  TreeItemme =  new TreeItem();

  me.text =  "我";

  me.itemIcon =  "./image/City.png";

  TreeItembrother = newTreeItem();

  brother.text =  "弟弟";

  brother.itemIcon =  "./image/City.png";

  family.children.Add(dad);

  dad.parent = family;

  family.children.Add(mom);

  mom.parent = family;

  family.children.Add(me);

  me.parent = family;

  family.children.Add(brother);

  brother.parent = family;

   // 把数据绑定到控件

  treeViewMine.ItemsSource = tree.children;

  }

转载于:https://www.cnblogs.com/hnfxs/archive/2013/03/26/2982706.html

WPF TreeView 控件默认提供了展开/折叠图标和单个CheckBox选中功能,如果需要实现扩展图标和多选功能,可以通过自定义TreeViewItem样式来实现。 下面是一个简单的示例,展示如何在WPF TreeView中实现扩展图标和多选功能: 1. 创建一个自定义TreeViewItem样式,并在其中添加一个扩展图标和多选CheckBox: ``` <Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <StackPanel Orientation="Horizontal" Grid.Column="0"> <Image x:Name="ExpandCollapseImage" Source="Expand.png" Width="16" Height="16" Margin="0,0,5,0" Visibility="Collapsed" /> <CheckBox x:Name="CheckBox" VerticalAlignment="Center" Margin="0,0,5,0"/> <ContentPresenter ContentSource="Header" /> </StackPanel> <ItemsPresenter Grid.Column="1" /> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="True"> <Setter TargetName="ExpandCollapseImage" Property="Source" Value="Collapse.png" /> <Setter TargetName="ExpandCollapseImage" Property="Visibility" Value="Visible" /> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="True"/> <Condition Property="IsSelectionActive" Value="True"/> </MultiTrigger.Conditions> <Setter TargetName="CheckBox" Property="IsChecked" Value="True"/> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> ``` 2. 在TreeView中应用自定义样式: ``` <TreeView x:Name="TreeView" ItemContainerStyle="{StaticResource TreeViewItemStyle}"> <!-- 树节点内容 --> </TreeView> ``` 3. 处理TreeViewItem的展开/折叠事件: ``` private void TreeViewItem_Expanded(object sender, RoutedEventArgs e) { TreeViewItem item = e.OriginalSource as TreeViewItem; if (item != null) { Image image = FindChild<Image>(item, "ExpandCollapseImage"); if (image != null) { image.Source = new BitmapImage(new Uri("Collapse.png", UriKind.Relative)); } } } private void TreeViewItem_Collapsed(object sender, RoutedEventArgs e) { TreeViewItem item = e.OriginalSource as TreeViewItem; if (item != null) { Image image = FindChild<Image>(item, "ExpandCollapseImage"); if (image != null) { image.Source = new BitmapImage(new Uri("Expand.png", UriKind.Relative)); } } } private T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject { if (parent == null) return null; T child = null; int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { DependencyObject childElement = VisualTreeHelper.GetChild(parent, i); if (childElement is T && ((FrameworkElement)childElement).Name == childName) { child = (T)childElement; break; } else { child = FindChild<T>(childElement, childName); if (child != null) break; } } return child; } ``` 4. 处理TreeViewItem的多选事件: ``` private void CheckBox_Click(object sender, RoutedEventArgs e) { TreeViewItem item = FindParent<TreeViewItem>(sender as DependencyObject); if (item != null) { // 获取父节点 TreeViewItem parentItem = FindParent<TreeViewItem>(item.Parent); if (parentItem != null) { // 获取所有子节点 List<TreeViewItem> childItems = new List<TreeViewItem>(); GetChildItems(parentItem, childItems); // 更新所有节点的多选状态 foreach (TreeViewItem childItem in childItems) { CheckBox checkBox = FindChild<CheckBox>(childItem, "CheckBox"); if (checkBox != null) { checkBox.IsChecked = GetChildCheckedState(parentItem); } } } } } private TreeViewItem FindParent<T>(DependencyObject child) where T : DependencyObject { if (child == null) return null; DependencyObject parent = VisualTreeHelper.GetParent(child); while (parent != null && !(parent is T)) { parent = VisualTreeHelper.GetParent(parent); } return parent as TreeViewItem; } private void GetChildItems(TreeViewItem item, List<TreeViewItem> childItems) { int childrenCount = VisualTreeHelper.GetChildrenCount(item); for (int i = 0; i < childrenCount; i++) { DependencyObject childElement = VisualTreeHelper.GetChild(item, i); if (childElement is TreeViewItem) { childItems.Add(childElement as TreeViewItem); GetChildItems(childElement as TreeViewItem, childItems); } } } private bool GetChildCheckedState(TreeViewItem parent) { int childrenCount = VisualTreeHelper.GetChildrenCount(parent); bool isChecked = false; for (int i = 0; i < childrenCount; i++) { DependencyObject childElement = VisualTreeHelper.GetChild(parent, i); if (childElement is TreeViewItem) { CheckBox checkBox = FindChild<CheckBox>(childElement as TreeViewItem, "CheckBox"); if (checkBox != null && checkBox.IsChecked == true) { isChecked = true; break; } else { isChecked = GetChildCheckedState(childElement as TreeViewItem); if (isChecked) break; } } } return isChecked; } ``` 通过以上步骤,我们就可以在WPF TreeView中实现扩展图标和多选功能了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值