通过双击名称更改 TabItem 的名称
Posted
技术标签:
【中文标题】通过双击名称更改 TabItem 的名称【英文标题】:Change a TabItem's name by double clicking the name 【发布时间】:2021-10-10 19:43:19 【问题描述】:我有一个TabControl
,我正在尝试允许用户更改选项卡名称...但仅在双击名称时。这样,用户可以单击不同的选项卡名称来简单地更改活动选项卡,还可以根据需要更改选项卡名称。
到目前为止我尝试过的是捕获MouseDoubleClick
和LostFocus
事件,然后仅在双击选项卡名称时将“Focusable”属性设置为true。此方法的问题是LostFocus
事件在双击后立即触发,可能是因为焦点被设置为 TabItem 的内容。
我的选项卡控件 XAML:
<Mah:MetroAnimatedTabControl x:Name="ViewTabs" DataContext="Binding MyTabsViewModel" ItemsSource="Binding">
<Mah:MetroAnimatedTabControl.ItemTemplate>
<DataTemplate DataType="x:Type viewModels:MyTabViewModel">
<TextBox x:Name="TabNameTextBox"
Text="Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
MouseDoubleClick="TabNameTextBox_MouseDoubleClick"
LostFocus="TabNameTextBox_LostFocus"
Cursor ="Arrow"/>
</DataTemplate>
</Mah:MetroAnimatedTabControl.ItemTemplate>
</Mah:MetroAnimatedTabControl>
事件MouseDoubleClick
和Lost Focus
背后的代码:
private void TabNameTextBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
var textBox = (TextBox)sender;
textBox.Focusable = true;
textBox.Focus();
textBox.SelectAll();
private void TabNameTextBox_LostFocus(object sender, RoutedEventArgs e)
var textBox = (TextBox)sender;
textBox.Focusable = false;
我发现了一个similar question,其中提问者无法触发Lost Focus
事件。在我的情况下,它在我预期之前就开始了。
【问题讨论】:
我会尝试以 MVVM 方式执行此操作,基本上将属性添加到viewModels:MyTabViewModel
类似于 IsRenaming
,然后当您处理鼠标双击时更改 IsRenaming
的值,这将基本上隐藏一个标签并使用Mah:MetroAnimatedTabControl.ItemTemplate
等中的绑定显示一个文本框
【参考方案1】:
我得到了以下内容以使用标准 WPF TabControl
。我的猜测是它也应该适用于Mah:MetroAnimatedTabControl
。
MainWindow.xaml:
<TabControl ItemsSource="Binding Items">
<TabControl.ItemTemplate>
<DataTemplate DataType="x:Type local:Item">
<Grid>
<TextBox x:Name="textBox" Text="Binding Name,UpdateSourceTrigger=PropertyChanged" LostFocus="textBox_LostFocus" Visibility="Collapsed"/>
<TextBlock x:Name="textBlock" Text="Binding Name" MouseDown="TextBlock_MouseDown"/>
</Grid>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate DataType="x:Type local:Item">
<TextBlock Text="Binding Contents"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
MainWindow.xaml.cs:
public partial class MainWindow : Window
private ObservableCollection<Item> items;
public MainWindow()
InitializeComponent();
Items.Add(new Item() Name = "Item 1" );
Items.Add(new Item() Name = "Item 2" );
Items.Add(new Item() Name = "Item 3" );
this.DataContext = this;
public ObservableCollection<Item> Items
get
if (items == null)
items = new ObservableCollection<Item>();
return items;
private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
if (e.ClickCount == 2 && e.ButtonState == MouseButtonState.Pressed)
var grid = (Grid)VisualTreeHelper.GetParent(sender as UIElement);
(sender as UIElement).Visibility = Visibility.Collapsed;
grid.Children[0].Visibility = Visibility.Visible;
grid.Children[0].Focus();
((TextBox)grid.Children[0]).SelectAll();
e.Handled = true;
private void textBox_LostFocus(object sender, RoutedEventArgs e)
var grid = (Grid)VisualTreeHelper.GetParent(sender as UIElement);
(sender as UIElement).Visibility = Visibility.Collapsed;
grid.Children[1].Visibility = Visibility.Visible;
Item.cs:
public class Item : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public Item()
this.PropertyChanged += OnItemPropertyChanged;
private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
if (e.PropertyName == nameof(Name))
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Contents)));
private string name;
public string Name get => name; set name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
public string Contents get => $"Contents of Name";
双击“Item 3”标题名称后的屏幕截图:
【讨论】:
以上是关于通过双击名称更改 TabItem 的名称的主要内容,如果未能解决你的问题,请参考以下文章