通过双击名称更改 TabItem 的名称
Change a TabItem's name by double clicking the name
我有一个 TabControl
并且我正在尝试允许用户更改选项卡名称...但只有当名称被双击时。这样,用户可以单击不同的选项卡名称来简单地更改活动选项卡,但也可以根据需要更改选项卡名称。
到目前为止我尝试过的 是捕获 MouseDoubleClick
和 LostFocus
事件,然后设置“可聚焦”属性仅当双击选项卡名称时为真。此方法的问题是 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
事件。在我的情况下,它在我预期之前就开始了。
我得到了以下与标准 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}"; }
}
我 double-clicked“项目 3”header 名称后的屏幕截图:
我有一个 TabControl
并且我正在尝试允许用户更改选项卡名称...但只有当名称被双击时。这样,用户可以单击不同的选项卡名称来简单地更改活动选项卡,但也可以根据需要更改选项卡名称。
到目前为止我尝试过的 是捕获 MouseDoubleClick
和 LostFocus
事件,然后设置“可聚焦”属性仅当双击选项卡名称时为真。此方法的问题是 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
事件。在我的情况下,它在我预期之前就开始了。
我得到了以下与标准 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}"; }
}
我 double-clicked“项目 3”header 名称后的屏幕截图: