在TreeView添加节点后有时后会需要修改节点的名称,这时就需要重命名功能。这里简单实现了右键菜单重命名,效果如下:

1、在TreeView的ItemTemplate中,在原来展示节点名称的位置放一个TextBox,当选择重命名操作时展示,操作完成时隐藏,添加右键按下事件来确定所选择的节点位置。

        <TreeView x:Name="treeView" Background="Transparent" MinHeight="280" Width="200"
                  ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Auto"
                  MouseDoubleClick="TreeView_MouseDoubleClick" MouseLeftButtonDown="TreeView_MouseLeftButtonDown" MouseRightButtonDown="TreeView_MouseRightButtonDown">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Path=ChildNodes}">
                        <TextBlock x:Name="showName" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,8,0,0" Height="26"
                                   FontSize="{Binding Path=SetFontSize}" FontWeight="{Binding Path=SetFontWeight}" Text="{Binding Path=NodeName, Mode=TwoWay}" />
                        <TextBox x:Name="reName" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,0,0" Height="22" Width="120"
                                 FontSize="{Binding Path=SetFontSize}" FontWeight="{Binding Path=SetFontWeight}" Text="{Binding Path=Name, Mode=TwoWay}" 
                                 Visibility="Collapsed" LostFocus="ReName_LostFocus"/>
                    </Grid>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
            <TreeView.ContextMenu>
                <ContextMenu x:Name="TreeViewMenu" Opened="TreeViewMenu_Opened">
                    <MenuItem x:Name="MenuReName" Header="重命名" Click="MenuReName_Click"/>
                    <MenuItem x:Name="MenuCopyItem" Header="复制" Command="Copy" InputGestureText="Ctrl+C"/>
                    <MenuItem x:Name="MenuPasteItem" Header="粘贴" Command="Paste" InputGestureText="Ctrl+V"/>
                    <MenuItem x:Name="MenuDeleteItem" Header="删除" Command="Delete" InputGestureText="Delete"/>
                </ContextMenu>
            </TreeView.ContextMenu>
            <TreeView.CommandBindings>
                <CommandBinding x:Name="Command_Copy" Command="Copy" CanExecute="Command_Copy_CanExecute" Executed="Command_Copy_Executed" />
                <CommandBinding x:Name="Command_Paste" Command="Paste" CanExecute="Command_Paste_CanExecute" Executed="Command_Paste_Executed" />
                <CommandBinding x:Name="Command_Delete" Command="Delete" CanExecute="Command_Delete_CanExecute" Executed="Command_Delete_Executed" />
            </TreeView.CommandBindings>
            <TreeView.InputBindings>
                <KeyBinding Command="Copy" Key="C"/>
                <KeyBinding Command="Paste" Key="V" />
                <KeyBinding Command="Delete" Key="Delete" />
            </TreeView.InputBindings>
        </TreeView>

2、添加重命名相关全局变量

        private TreeViewItem reNameTreeViewItem = null;//需要重命名的TreeViewItem
        private TreeViewNode reNameSelectNode = null;//需要重命名的节点
        private TextBox reNameTextBox = new TextBox();//需要重命名的TextBox
        private bool isReName = false;//是否正在重命名节点,避免重命名未完成时拖拽节点

3、在右键菜单打开事件中加入重命名使能判断

        private void TreeViewMenu_Opened(object sender, RoutedEventArgs e)
            TreeViewNode selectNode = (TreeViewNode)treeView.SelectedItem;
            ((MenuItem)TreeViewMenu.Items[0]).IsEnabled = ((MenuItem)TreeViewMenu.Items[1]).IsEnabled = ((MenuItem)TreeViewMenu.Items[2]).IsEnabled = ((MenuItem)TreeViewMenu.Items[3]).IsEnabled = selectNode != null && !selectNode.IsNodeAdd && !selectNode.IsChildNodeAdd;

4、重命名相关事件逻辑

        /// <summary>
        /// 右键按下时赋值重命名节点数据
        /// </summary>
        private void TreeView_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
            TreeViewNode selectNode = (TreeViewNode)this.treeView.SelectedItem;
            if (selectNode == null || selectNode.IsNodeAdd || selectNode.IsChildNodeAdd) return;
            reNameTreeViewItem = GetParentObjectEx<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
            if (reNameTreeViewItem != null)
                //使当前节点获得焦点
                reNameTreeViewItem.Focus();
                reNameSelectNode = selectNode;
        /// <summary>
        /// 获取父控件
        /// </summary>
        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;
        /// <summary>
        /// 右键菜单重命名
        /// </summary>
        private void MenuReName_Click(object sender, RoutedEventArgs e)
            if (!reNameSelectNode.IsNodeAdd && !reNameSelectNode.IsChildNodeAdd)
                if (reNameTreeViewItem != null && !((TreeViewNode)reNameTreeViewItem.DataContext).IsNodeAdd && !((TreeViewNode)reNameTreeViewItem.DataContext).IsChildNodeAdd)
                    //使当前节点获得焦点
                    reNameTreeViewItem.Focus();
                    //获取在TreeView.ItemTemplate中定义的TextBox控件
                    reNameTextBox = FindVisualChild<TextBox>(reNameTreeViewItem as DependencyObject);
                    //设置该TextBox的Visibility 属性为Visible
                    reNameTextBox.Visibility = Visibility.Visible;
                    reNameTextBox.SelectAll();
                    reNameTextBox.Focus();
                    isReName = true;
        /// <summary>
        /// 获取子控件
        /// </summary>
        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;
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
            return null;
        /// <summary>
        /// 失去焦点后处理重命名逻辑
        /// </summary>
        private void ReName_LostFocus(object sender, RoutedEventArgs e)
            isReName = false;
            if (reNameTextBox == null) return;
            if (reNameSelectNode == null || reNameSelectNode.IsNodeAdd || reNameSelectNode.IsChildNodeAdd)
                reNameTextBox.Visibility = Visibility.Collapsed;
                return;
            //输入为空
            if (reNameTextBox.Text.Trim() == "")
                reNameTextBox.Text = reNameSelectNode.NodeName;
                reNameTextBox.Visibility = Visibility.Collapsed;
                return;
            //最多6个字符
            if (reNameTextBox.Text.Trim().Length > 6)
                MessageBox.Show("最多六个字符");
                reNameTextBox.Text = reNameSelectNode.NodeName;
                reNameTextBox.Visibility = Visibility.Collapsed;
                return;
            //重名判断
            TreeViewNode reNameParentNode = reNameSelectNode.ParentId == TopNodeId ? TopNode : TopNode.ChildNodes[reNameSelectNode.ParentId];
            if (!CheckNodeNameAdd(reNameParentNode, reNameTextBox.Text.Trim()))
                MessageBox.Show("与现有节点名称重名");
                reNameTextBox.Text = reNameSelectNode.NodeName;
                reNameTextBox.Visibility = Visibility.Collapsed;
                return;
            //重命名
            reNameTextBox.Visibility = Visibility.Collapsed;
            reNameSelectNode.NodeName = reNameTextBox.Text.Trim();

5、在拖拽移动事件TreeView_MouseMove中加入isReName的逻辑

        /// <summary>
        /// 拖拽移动
        /// </summary>
        private void TreeView_MouseMove(object sender, MouseEventArgs e)
            if (e.LeftButton == MouseButtonState.Pressed && !isReName)
                ......
                ......

相关博文:

WPF一个完整的TreeView使用实例:(一)自定义控件样式+数据源绑定+动态添加父子节点

WPF一个完整的TreeView使用实例:(二)拖拽改变父子节点层级

WPF一个完整的TreeView使用实例:(三)右键菜单复制+粘贴+删除

WPF一个完整的TreeView使用实例:(四)节点重命名

if (nodeInfoList[i].nodeToolTipText == nodeChange) treeView1.SelectedNode.EndEdit(true); MessageBox.Show("名为“" + newName + "”的项已存在,请为您要添加的项提供一个唯一的名称")... 二、实现代码 首先为TreeView控件生成一个双击事件,选择闪电一样的按钮,找到 DoubleClick 这一项双击,会自动生成相应的事件,同样方法生成 MouseDown 事件和 AfterLabelEdit 事件。 private Point pi;//定义一个坐标变量 //editMenuTree为TreeView的Name private void editMenuTree_MouseDown(object sender,
前言:TreeView可以说是很常见的一个控件,大部分软件不管是客户端还是网页都会有个左侧树型结构的控件,用于承载树形数据,下面就TreeView在MVVM下的使用写两篇小记,一篇是绑定后台数据,一篇是选中事件后获取路由节点信息。 说明:有关MVVM的介绍,可以导航到这篇文章了解下wpf mvvm小记 其中MVVM使用prism框架,这样就不需要自己重新去实现MVVM的功能了,prism中都封装好了。 Prism的简单介绍可以看笔者之前的文章了解下。 一、目录结构 二、测试实现功能
WPF Window.RenderTransform 可以用于对窗口进行变换操作,例如旋转、缩放、平移等。具体使用实例可以参考以下代码: <Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Button Content="Click Me" Width="100" Height="50" RenderTransformOrigin=".5,.5"> <Button.RenderTransform> <RotateTransform Angle="45"/> </Button.RenderTransform> </Button> </Grid> </Window> 以上代码中,我们在按钮上应用了一个旋转变换,使其旋转了45度。通过 RenderTransformOrigin 属性可以指定变换的中心点。