WFP TreeView使用及注意事项

最近接手WPF的项目,从0开始,做些积累

Demo地址:https://github.com/AlbinZhang/WPF_Pratice.git 里面的001_TreeView_Model

0.效果图

这里写图片描述

1. TreeView使用模版

参考链接:
Treeview - http://www.cnblogs.com/_ymw/p/3450345.html

HierarchicalDataTemplate - http://www.cnblogs.com/goldren/archive/2012/12/11/2812697.html

HierarchicalDataTemplate顾名思义,分层数据模板,就是用来定义分层数据样式的模板,一般多用于MenuItem和TreeViewItem
    DataType指定模板用于哪种数据类型
    ItemsSource指定该类数据的子集,即下一层显示那些数据
    内容 指定数据如何显示 绑定哪个属性
//-------XMAL
xmlns:local="clr-namespace:_001_TreeView_Model"

<Grid.Resources>
    <HierarchicalDataTemplate x:Key="TreeTemplate" DataType="{x:Type local:Node}" ItemsSource="{Binding Nodes}">
        <StackPanel Orientation="Horizontal"  Margin="2,3,2,3"  >
            <Image Source="{Binding Image}" Width="18" Height="18" Margin="0,0,5,0" />
            <CheckBox Margin="0, 5"  IsChecked="{Binding bClick}" ></CheckBox>
            <Label Content="{Binding Name}"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</Grid.Resources>

<TreeView Name="tvTreeView"  Grid.Column="0"  ItemTemplate="{StaticResource TreeTemplate}">

//--------Code

List<Node> outputList = new List<Node>();

tvTreeView.ItemsSource = outputList;

public class Node
{
    public Node()
    {
        this.Nodes = new List<Node>();
        this.ParentID = -1;
        this.Image = "D:/Code/C#/001_TreeView_Model/001_TreeView_Model/link.png";
    }
    public int ID { get; set; }
    public string Name { get; set; }
    public string Image { get; set; }
    public bool bClick { get; set; }

    public int ParentID { get; set; }
    public List<Node> Nodes { get; set; }
}

2.点击checkBox获取当前TreeViewItem的DataContent

这个需要先从视觉树上获取到TreeViewItem
    下面是打印当前视觉树的函数,先知道树什么样才能取
string treeStr = "";
void printVisualTree(int depth, DependencyObject obj)
{
    treeStr += new string(' ', depth) + obj + "\r\n"; //打印空格,方便查看

    //递归打印视觉树
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        printVisualTree(depth + 1, VisualTreeHelper.GetChild(obj, i));
    }
}
利用上面的打印函数,打印 TreeView 的视觉树,然后确定怎么获取到TreeViewItem的对象
printVisualTree(0, tvTreeView);


///////////////
System.Windows.Controls.TreeView Items.Count:1
 System.Windows.Controls.Border
  System.Windows.Controls.ScrollViewer
   System.Windows.Controls.Grid
    System.Windows.Shapes.Rectangle
    System.Windows.Controls.ScrollContentPresenter
     System.Windows.Controls.ItemsPresenter
      System.Windows.Controls.StackPanel
       System.Windows.Controls.TreeViewItem 标题:_001_TreeView_Model.Node Items.Count:3
        System.Windows.Controls.Grid
         System.Windows.Controls.Primitives.ToggleButton 内容: IsChecked:False
          System.Windows.Controls.Border
           System.Windows.Shapes.Path
         System.Windows.Controls.Border
          System.Windows.Controls.ContentPresenter
           System.Windows.Controls.StackPanel
            System.Windows.Controls.Image
            System.Windows.Controls.CheckBox 内容: IsChecked:True
             System.Windows.Controls.Grid
              System.Windows.Controls.Border
               System.Windows.Controls.Grid
                System.Windows.Shapes.Path
                System.Windows.Shapes.Rectangle
              System.Windows.Controls.ContentPresenter
            System.Windows.Controls.Label: 中国
             System.Windows.Controls.Border
              System.Windows.Controls.ContentPresenter
               System.Windows.Controls.TextBlock
         System.Windows.Controls.ItemsPresenter
     System.Windows.Documents.AdornerLayer
    System.Windows.Controls.Primitives.ScrollBar 最小值:0 最大值:0 值:0
    System.Windows.Controls.Primitives.ScrollBar 最小值:0 最大值:0 值:0
使用下面函数获取TreeViewItem
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
    CheckBox cb = sender as CheckBox;
    TreeViewItem Item = (TreeViewItem)VisualUpwardSearch<TreeViewItem>(cb);

    Node node = Item.DataContext as Node;

    MessageBox.Show(string.Format("{0} is Click({1})", node.Name, node.bClick));
}

DependencyObject VisualUpwardSearch<T>(DependencyObject source)  //搜寻可视话树的父节点
{
    while (source != null && source.GetType() != typeof(T))
        source = VisualTreeHelper.GetParent(source);
    return source;
}

3. TreeViewItem绑定MouseLeftButtonDown 事件,并使其生效

参考连接:http://stackoverflow.com/questions/30356236/mouseleftbuttondown-event-not-raised-in-treeviewitem-why

首先通过style的方式给TreeViewItem绑定上MouseLeftButtonDown事件,并且直接绑定鼠标事件是不响应的,
stackoverflow上的说法是在TreeViewItem中的TreeViewItem.OnMouseLeftButtonDown事件在Item获取到焦点的时候,
    事件就已经被标记了,然后LeftButtonDown就获取不到事件,所以无法响应
    只要先不让TreeViewItem的获取到焦点,LeftButtonDown就获取到事件了    (不知道多少把刀的水平,勿喷,建议直接看链接)
//---------XMAL
<TreeView Name="tvTreeView"  Grid.Column="0"  ItemTemplate="{StaticResource TreeTemplate}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Setters>
                <Setter Property="Focusable" Value="False"/>  <!-- 就是使当前item不能获取焦点 -->
                <EventSetter Event="MouseLeftButtonDown" Handler="tvTreeViewItem_MouseLeftButtonDown" />
            </Style.Setters>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

//----------Code
private void tvTreeViewItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("TreeViewItem MouseLeftButtonDown");

    TreeViewItem item = sender as TreeViewItem;

    //下面部分是可以让item临时获取焦点,UI上有选中的效果
    item.Focusable = true;
    item.Focus();
    item.Focusable = false;
    e.Handled = true;
}

4. 收缩所有子节点

private void Contract_Click(object sender, RoutedEventArgs e)
{
    TreeViewItem root = (TreeViewItem)tvTreeView.ItemContainerGenerator.ContainerFromIndex(0);
    if (root != null)
    {
        CollapseTreeviewItems(root);
    }
}


private void CollapseTreeviewItems(TreeViewItem Item)
{
    Item.IsExpanded = false;

    foreach (var item in Item.Items)
    {
        DependencyObject dObject = tvTreeView.ItemContainerGenerator.ContainerFromItem(item);

        if (dObject != null)
        {
            ((TreeViewItem)dObject).IsExpanded = false;

            if (((TreeViewItem)dObject).HasItems)
            {
                CollapseTreeviewItems(((TreeViewItem)dObject));
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值