WPF 中带有 TextBox 的 TreeViewItem:单击 TextBox 时如何选择包含 TextBox 的 TreeViewItem
TreeViewItem with TextBox in WPF: How selected TreeViewItem containing a TextBox when clicking on TextBox
我有一个 TreeView,使用 TextBox 显示信息,具有编辑功能。
但是 TextBox 会停止 MouseDown 事件,并且在单击 TextBox 时不会选择 TreeViewItem。
如何通过保留编辑文本的能力来解决这个问题。
可能的最小示例:在此代码中,未触发 SelectedItemChanged 事件,因为未选择任何项目。
<Window x:Class="TreeViewItemSelected.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBlock x:Name="text" FontSize="20" HorizontalAlignment="Center" />
<TreeView x:Name="tree" FontSize="20" ItemsSource="{Binding Items}" SelectedItemChanged="tree_SelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBox Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</Window>
using System.Collections.ObjectModel;
using System.Windows;
namespace TreeViewItemSelected
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new VM();
}
private void tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (e.NewValue is testitem item) text.Text = item?.Name;
}
}
public class VM
{
public VM()
{
testitem item = new testitem("Aaaaaaa");
item.Items.Add(new testitem("Aaa 1"));
item.Items.Add(new testitem("Aaa 2"));
item.Items.Add(new testitem("Aaa 3"));
Items.Add(item);
item = new testitem("Bbbbbbb");
item.Items.Add(new testitem("Bbb 1"));
item.Items.Add(new testitem("Bbb 2"));
item.Items.Add(new testitem("Bdd 3"));
Items.Add(item);
Items.Add(new testitem("Ccccccc"));
Items.Add(new testitem("Ddddddd"));
Items.Add(new testitem("Eeeeeee"));
}
public ObservableCollection<testitem> Items { get; set; } = new ObservableCollection<testitem>();
}
public class testitem
{
public string Name { get; set; }
public testitem(string name) => Name = name;
public ObservableCollection<testitem> Items { get; set; } = new ObservableCollection<testitem> {};
}
}
我尝试使用它,但它没有像我预期的那样工作。可能是我用错了。
AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(StackPanel_MouseDown), true);
或
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
提前致谢!
一种直接的方法是将 TextBox
的 IsKeyboardFocused
属性 与 TreeViewItem
的 IsSelected
属性 连接起来。 Microsoft.Xaml.Behaviors.Wpf.
可以轻松完成
<TextBox Text="{Binding Name}">
<i:Interaction.Triggers>
<i:DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBox}}, Path=IsKeyboardFocused}" Value="True">
<i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
PropertyName="IsSelected" Value="True"/>
</i:DataTrigger>
</i:Interaction.Triggers>
</TextBox>
我有一个 TreeView,使用 TextBox 显示信息,具有编辑功能。 但是 TextBox 会停止 MouseDown 事件,并且在单击 TextBox 时不会选择 TreeViewItem。 如何通过保留编辑文本的能力来解决这个问题。
可能的最小示例:在此代码中,未触发 SelectedItemChanged 事件,因为未选择任何项目。
<Window x:Class="TreeViewItemSelected.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBlock x:Name="text" FontSize="20" HorizontalAlignment="Center" />
<TreeView x:Name="tree" FontSize="20" ItemsSource="{Binding Items}" SelectedItemChanged="tree_SelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<TextBox Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</Window>
using System.Collections.ObjectModel;
using System.Windows;
namespace TreeViewItemSelected
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new VM();
}
private void tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (e.NewValue is testitem item) text.Text = item?.Name;
}
}
public class VM
{
public VM()
{
testitem item = new testitem("Aaaaaaa");
item.Items.Add(new testitem("Aaa 1"));
item.Items.Add(new testitem("Aaa 2"));
item.Items.Add(new testitem("Aaa 3"));
Items.Add(item);
item = new testitem("Bbbbbbb");
item.Items.Add(new testitem("Bbb 1"));
item.Items.Add(new testitem("Bbb 2"));
item.Items.Add(new testitem("Bdd 3"));
Items.Add(item);
Items.Add(new testitem("Ccccccc"));
Items.Add(new testitem("Ddddddd"));
Items.Add(new testitem("Eeeeeee"));
}
public ObservableCollection<testitem> Items { get; set; } = new ObservableCollection<testitem>();
}
public class testitem
{
public string Name { get; set; }
public testitem(string name) => Name = name;
public ObservableCollection<testitem> Items { get; set; } = new ObservableCollection<testitem> {};
}
}
我尝试使用它,但它没有像我预期的那样工作。可能是我用错了。
AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(StackPanel_MouseDown), true);
或
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
提前致谢!
一种直接的方法是将 TextBox
的 IsKeyboardFocused
属性 与 TreeViewItem
的 IsSelected
属性 连接起来。 Microsoft.Xaml.Behaviors.Wpf.
<TextBox Text="{Binding Name}">
<i:Interaction.Triggers>
<i:DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBox}}, Path=IsKeyboardFocused}" Value="True">
<i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
PropertyName="IsSelected" Value="True"/>
</i:DataTrigger>
</i:Interaction.Triggers>
</TextBox>