通过双击名称更改 TabItem 的名称

Posted

技术标签:

【中文标题】通过双击名称更改 TabItem 的名称【英文标题】:Change a TabItem's name by double clicking the name 【发布时间】:2021-10-10 19:43:19 【问题描述】:

我有一个TabControl,我正在尝试允许用户更改选项卡名称...但仅在双击名称时。这样,用户可以单击不同的选项卡名称来简单地更改活动选项卡,还可以根据需要更改选项卡名称。

到目前为止我尝试过的是捕获MouseDoubleClickLostFocus 事件,然后仅在双击选项卡名称时将“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>

事件MouseDoubleClickLost 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 的名称的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Xcode 中更改产品名称

康耐视相机更改相机名称

苹果手机软件名称修改

错误代码:1046。未选择数据库 通过在侧边栏中的 SCHEMAS 列表中双击其名称来选择要使用的默认数据库

如何通过命令行更改 Gerrit 的主题名称

wpf 如何在tabContrl页中显示一个xaml页