How does WPF rename a TreeView Node? wpftreeview Node
We often see some software such as codoy music. When you right-click the list and rename it, the current list will be white and editable. After the change is complete, it will go into the non-editable status, how are these implemented? The following method may provide some ideas. The following TreeView node is bound to the Text attribute of the TextBlock control and TextBox Control through two-way data binding, in addition, bind the two to the same property and make the TextBox Control exactly overwrite the TextBlock control. Due to the differences between the TextBlock control and the TextBox Control, the TextBlock control cannot be edited, therefore, I overwrite a TextBox Control on the TextBlock control. In the initial state, we set the Visibility attribute of the TextBox to Collapsed. When we click rename, set the Visibility attribute of TextBox to Visible, so that we can rename the node. Of course, after the name is complete (after the TextBox loses focus) we set the Visibility attribute of TextBox to Collapsed to complete the rename process. Of course, we still have a lot of important work to do, such as how to obtain Hierarc The TextBox Control in the hicalDataTemplate is the key. Secondly, the TextBlock control and the TextBox control must be bound to the same attribute at the same time, so that when the attribute value changes, the Text attribute value of the TextBlock can be changed. Note: The default binding Mode of TextBox is Mode = TwoWay.
Front-end XAML code (key part)
<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 = "RENAME" Click = "ReNameTreeViewItem_Click">
</MenuItem>
</ContextMenu>
</CheckBox. ContextMenu>
</CheckBox>
</HierarchicalDataTemplate>
</TreeView. ItemTemplate>
Core back-end code:
// The following part occurs when the mouse pointer is on this element (TreeViewItem) And you right-click it.
Private void TreeViewItem_PreviewMouseRightButtonDown (object sender, MouseButtonEventArgs e)
{
// Here, item defines a member variable of the class and a TreeViewItem type.
Item = GetParentObjectEx <TreeViewItem> (e. OriginalSource as DependencyObject) as TreeViewItem;
If (item! = Null)
{
// Focus the current node
Item. Focus ();
// The system no longer processes the operation.
E. Handled = true;
}
}
// Rename the current TreeViewItem
Private void ReNameTreeViewItem_Click (object sender, RoutedEventArgs e)
{
// Obtain the TextBox Control defined in TreeView. ItemTemplate.
TempTextBox = FindVisualChild <TextBox> (item as DependencyObject );
// Set the Visibility of the TextBox The property isVisible
TempTextBox. Visibility = Visibility. Visible;
}
The following function uses the VisualTreeHelper. GetParent () method to obtain various controls on the visual tree. When we click the TreeView node, we can search and obtain them from the visual tree in sequence.
The corresponding controls found in this example are: textBlock-> StackPanel-> ContentPresenter-> BulletDecorator-> CheckBox-> ContentPresenter-> Boarder-> Grid-> TreeViewItem, find the expected TreeViewItem object through each upward search.
// Obtain the TreeViewItem of the current TreeView
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;
}
The following function is also very important, because the TextBox Control we define is in the TreeView. as defined in ItemTemplate, you cannot use this to find the current control. If you cannot obtain the current control, you cannot perform the following operations. Therefore, this function is also very important. Unlike clicking the mouse, you can search up the visual tree. Here, you need to search down the visual tree until the TextBox Control is found, and the TextBox control object is finally returned, this is just the opposite of the above process, but this process is also very important. For specific usage instructions, refer to MSDN for more detailed instructions.
// Obtain various controls in 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;
}
// This event occurs when TextBox loses focus
Private void renametextbox_LostFous (object sender, RoutedEventArgs e)
{
TempTextBox. Visibility = Visibility. Collapsed;
}