WPF Treeview 学习 图标,checkbox,右键菜单

WPF Treeview 学习

最近在学习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<TreeItem>();

       }

 

       //

       // 节点文字信息

       public stringtext

       {

           get;

            set;

       }

       // 节点其他信息

       // ...

 

       // 父节点

       public TreeItemparent

       {

            get;

            set;

       }

       // 子节点

       public ObservableCollection<TreeItem> 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

       {

            get{ return _isChecked;}

            set{ this.SetIsChecked(value, true, true); }

       }

 

       void SetIsChecked(bool? value, bool updateChildren,bool updateParent)

       {

            if(value == _isChecked)

                return;

 

            _isChecked= value;

 

            if(updateChildren && _isChecked.HasValue)

            {

                foreach(TreeItem childin children)

                {

                    child.SetIsChecked(_isChecked,true, false);

                }

            }

 

            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,false, true);

       }

       

       

      

       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;

        }

2、  tree的节点选择

在当前选择项(非checkbox)下加一个节点:

TreeItem selectItem = treeViewMine.SelectedItem as TreeItem;

 

            if(selectItem != null)

            {

                TreeItemnewItem = newTreeItem();

                newItem.text = "这是一个新项";

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

                selectItem.children.Add(newItem);

                newItem.parent = selectItem;

            }

 

删除获得焦点的选择项:

TreeItem selectItem = treeViewMine.SelectedItem as TreeItem;

            selectItem.parent.children.Remove(selectItem);

 

删除checkbox选择的项

private void button1_Click(object sender, RoutedEventArgs e)

       {

            TreeDelChecked(tree);

       }

 

       bool TreeDelChecked(TreeItem item)

       {

            begin:

            foreach(TreeItem itemChildin item.children)

            {

                // 如果删除一个子节点后,foreach要重新遍历

                if(TreeDelChecked(itemChild))

                {

                    gotobegin;

                }

            }

 

           if(item.IsChecked.HasValue) //check for avalue

            {

                if((bool)item.IsChecked && item.parent != null) //now this cast is safe

                {                   

                    item.parent.children.Remove(item);

 

                    returntrue;

                }

            }

 

            returnfalse;

       }

 

3、树右键选中和右键菜单

参考《在WPF的TreeView中实现右键选定》http://www.cnblogs.com/TianFang/archive/2010/02/10/1667153.html

 

<TreeView.ItemContainerStyle >

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

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

                    <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="treeViewMine_PreviewMouseRightButtonDown"/>

                </Style>

            </TreeView.ItemContainerStyle>

 

private void treeViewMine_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)

       {

            TreeViewItemitem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) asTreeViewItem;

            if(item != null)

            {

                item.ContextMenu = GetItemRightContextMenu();

 

                item.Focus();

                e.Handled = true; 

            }

       }

 

       static DependencyObjectVisualUpwardSearch<T>(DependencyObjectsource)

       {

            while(source != null&& source.GetType()!= typeof(T))

                source= VisualTreeHelper.GetParent(source);

 

            returnsource;

       }

 

       // 获得右键上下文菜单

       ContextMenu GetItemRightContextMenu()

       {

            ContextMenumenu = new ContextMenu();

            MenuItemmenuItem = newMenuItem();

            menuItem.Header = "菜单";

            menuItem.Click += new RoutedEventHandler(treeMenu_Click);

            menu.Items.Add(menuItem);

 

            returnmenu;

       }

 

       private voidtreeMenu_Click(objectsender, RoutedEventArgse)

       {

            if(MessageBox.Show("大家好,我是树的右键菜单事件!", "提示", MessageBoxButton.OKCancel,MessageBoxImage.Information)!= MessageBoxResult.OK)

            {

                return;

            }

  }

 

代码:http://download.csdn.net/source/3442625     (http://alsmile.download.csdn.net/

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值