我们经常看到一些软件比如酷狗音乐,在对列表右键进行重命名的时候,当前列表会泛白并且进入可编辑状态,当我们更改完成后就会并进入非编辑状态,这些具体是怎么实现的呢?下面的方法也许会提供一些思路,下面的TreeView节点是通过数据双向绑定的方式,绑定到TextBlock控件和TextBox控件的Text属性上,并且让两者绑定相同的属性,同时使TextBox控件刚好完全覆盖TextBlock控件, 由于TextBlock控件和TextBox控件的区别,TextBlock控件无法实现编辑,所以我在TextBlock控件的上面覆盖了一个TextBox控件,初始状态下我们设置TextBox的Visibility属性为Collapsed当我们点击重命名的时候,我们再设置TextBox的Visibility属性为Visible,这样我们就能够进行节点的重命名,当然当我们命名完成后(该TextBox失去焦点之后)我们再设置TextBox的Visibility属性为Collapsed,这样就完成了重命名的过程,当然我们还有很多重要的工作要做,比如如何获取HierarchicalDataTemplate中的TextBox控件这个是关键,其次TextBlock控件和TextBox控件必须同时绑定到同一属性,这样当属性值发生改变时,就能够更改TextBlock的Text属性值。注意:TextBox的默认绑定方式Mode=TwoWay。

前端XAML代码(关键部分)

<TreeView.ItemTemplate>

<HierarchicalDataTemplate DataType="{x:Type localex:TreeMode}" ItemsSource="{Binding Children}">

<CheckBox Tag="{Binding Children}" IsChecked="{Binding IsChecked, Mode=TwoWay}" ToolTip="{Binding ToolTip}">

<StackPanel Orientation="Horizontal">

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

<StackPanel Orientation="Vertical">

<TextBlock Text="{Binding Name, Mode=TwoWay}" HorizontalAlignment="Center" Width="Auto"/>

<TextBox x:Name="renametextbox" Text="{Binding Name, Mode=TwoWay}" HorizontalAlignment="Center" Margin="0,-20,0,0"

Width="Auto"  Visibility="Collapsed"  LostFocus="renametextbox_LostFous"/>

</StackPanel>

</StackPanel>

<CheckBox.ContextMenu>

<ContextMenu>

<MenuItem  Name="reNameItem" Header="重命名" Click="ReNameTreeViewItem_Click">

</MenuItem>

</ContextMenu>

</CheckBox.ContextMenu>

</CheckBox>

</HierarchicalDataTemplate>

</TreeView.ItemTemplate>

后端核心代码:

//下面的部分是在鼠标指针位于此元素(TreeViewItem)上并且按下鼠标右键时发生。

private void TreeViewItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {

//此处item定义的是一个类的成员变量,是一个TreeViewItem类型
             item = GetParentObjectEx<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
             if (item != null)
              {

//使当前节点获得焦点
                 item.Focus();

//系统不再处理该操作

e.Handled = true;

}
        }

//对当前TreeViewItem进行重命名

private void ReNameTreeViewItem_Click(object sender, RoutedEventArgs e)

{

//获取在TreeView.ItemTemplate中定义的TextBox控件

             tempTextBox = FindVisualChild<TextBox>(item as DependencyObject);

            //设置该TextBox的Visibility 属性为Visible

             tempTextBox.Visibility = Visibility.Visible;

}

下面的这个函数主要是利用VisualTreeHelper.GetParent()方法获取视觉树上面的各种控件,当我们鼠标点击TreeView节点的时候,我们沿着视觉树VisualTree依次向上查找获取

相应的控件,在本例中依次查找到的控件为:TextBlock-》StackPanel-》StackPanel-》ContentPresenter-》BulletDecorator-》CheckBox-》ContentPresenter-》Boarder-》Grid-》TreeViewItem,通过每一次的向上查找最终找到我们需要的TreeViewItem对象。

//获取当前TreeView的TreeViewItem
      public TreeViewItem GetParentObjectEx<TreeViewItem>(DependencyObject obj) where TreeViewItem : FrameworkElement
      {
        DependencyObject parent = VisualTreeHelper.GetParent(obj);
        while (parent != null)
         {
            if (parent is TreeViewItem)
           {
               return (TreeViewItem)parent;
           }
              parent = VisualTreeHelper.GetParent(parent);
        }
         return null;
      }

下面的这个函数也是非常重要的,由于我们定义的TextBox控件是在TreeView.ItemTemplate中定义的,所以无法通过this来查找当前的控件,如果无法获取当前的该控件,就无法进行下面的操作,所以这个函数也是非常重要的。和鼠标点击是沿着视觉树向上查找不同,此处我们需要沿着视觉树向下查找,直到找到我们TextBox控件为止,最终返回TextBox控件对象,这个刚好和上面的过程相反,但是这个过程也是非常重要的,具体的使用方式可以参考MSDN上面有更加具体的说明。

//获取ItemTemplate内部的各种控件

private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject

{

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)

{

DependencyObject child = VisualTreeHelper.GetChild(obj, i);

if (child != null && child is childItem)

return (childItem)child;

else

{

childItem childOfChild = FindVisualChild<childItem>(child);

if (childOfChild != null)

return childOfChild;

}

}

return null;

}

//当TextBox失去焦点时发生此事件

private void renametextbox_LostFous(object sender, RoutedEventArgs e)

{

tempTextBox.Visibility = Visibility.Collapsed;

}

WPF如何实现TreeView节点重命名的更多相关文章

  1. WPF 之 TreeView节点重命名

    下面的TreeView节点是通过数据双向绑定的方式,绑定到TextBlock控件和TextBox控件的Text属性上,并且让两者绑定相同的属性,同时使TextBox控件刚好完全覆盖TextBlock控 ...

  2. C# Xml.Serialization 节点重命名

    XmlElement 节点重命名 XmlRoot 根节点重名称 XmlArray List集合添加根节点 XmlArrayItem List集合中子节点重命名 [Serializable] 将该类标记 ...

  3. WPF 之 TreeView右键选中节点及节点重命名

    下面的TreeView节点是通过数据双向绑定的方式,绑定到TextBlock控件和TextBox控件的Text属性上,并且让两者绑定相同的属性,同时使TextBox控件刚好完全覆盖TextBlock控 ...

  4. c# winform TreeView NODE(节点) 重命名或获取节点修改后的值

    在程序开发过程中我们经常用到treeview,还经常要修改节点的名字.节点名字修改后还想及时更新数据库.这时问题就来了,怎样获取NODE(节点)更新后的值呢?本人试了很多方法最终分析出treeview ...

  5. WinForm TreeView节点重绘,失去焦点的高亮显示

    当用户焦点离开TreeView时,TreeView选中节点仍然高亮,但是颜色符合主题. 设置TreeView.HideSelection = False;可让选中节点保持高亮. 添加重绘事件 Tree ...

  6. C# 运行时编辑 节点重命名

    方法一: ; bool nodeChanged = false; //右键点击,就进入修改状态 private void treeView1_NodeMouseClick(object sender, ...

  7. Winform中node.Text重命名时窗口无响应假死的解决方法

    用户控件中有一个树,窗体使用了这个控件,但是重命名时执行node.text="XXXX" 执行了很长时间,大约9s,在此期间winform界面假死,尝试过多线程异步委托的方式来操作 ...

  8. WPF如何用TreeView制作好友列表、播放列表

    WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...

  9. WPF如何用TreeView制作好友列表、播放列表(转)

    WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...

随机推荐

  1. Leetcode:234 回文链表

    leetcode:234 回文链表 关键点:请判断一个链表是否为回文链表.示例 1:输入: 1->2输出: false示例 2:输入: 1->2->2->1输出: true. ...

  2. 【vue】vue +element 搭建项目,$createElement使用

    语法: 它有三个参数 第一个:html标签名 第二个:配置的数据对象 第三个:内容 应用1:自定义弹窗 html: <el-button type="text" @click ...

  3. 【vue】vue +element 搭建项目,组件之间通信

    父子组件通信 父 通过props属性给 子传递数据 子 操作 父  this.$parent.XXX 子通过$emit传递参数 或者通过vue-bus vue-bus既可以实现父子组件之间的通信,也可 ...

  4. 01 python初学(注释、交互、if while for)

    为了能生存下去,一定要坚持学习! 目录  1. 注释 2. 用户交互 3. if .while.for 语句 1. 注释  单行注释: # 多行注释: 三个单引号 || 三个双引号 2. 用户交互: ...

  5. day2-安装python以及基本使用

    安装Python windows 1.下载安装包 https://www.python.org/downloads/ 2.安装 默认安装路径:C:\python27 3.配置环境变量 [右键计算机]- ...

  6. java对象比较

    public class InternDemo { public static void main(String[] args){ /* jdk7版本之后 字符串常量池从Perm Space移到Jav ...

  7. windwos 下编译minicap

    一.参考github 介绍:https://github.com/openstf/minicap Requirements (前提) NDK, Revision 10e (May 2015) make ...

  8. k8s 节点的 NodeAffinity 使用

    apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: vi ...

  9. C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)

    上一讲<C++11 并发指南四(<future> 详解一 std::promise 介绍)>主要介绍了 <future> 头文件中的 std::promise 类, ...

  10. pip install报错Can't roll back cryptography; was not uninstalled

    当使用pip install或者pip install --upgrade报错 Can't roll back cryptography; was not uninstalled 可以进行以下的尝试: ...