用于 RibbonTab 的 WPF IsSelected 绑定在 ctrl+tab 上停止工作

Posted

技术标签:

【中文标题】用于 RibbonTab 的 WPF IsSelected 绑定在 ctrl+tab 上停止工作【英文标题】:WPF IsSelected binding for RibbonTab stops working upon ctrl+tab 【发布时间】:2013-03-19 10:43:09 【问题描述】:

这是RibbonTab IsSelected not working 的最小化错误重现。

这是演示应用程序的主窗口:

当我们点击应用程序菜单(蓝色箭头)时,会弹出一个菜单。

如果我们点击主视图,一个标签项会被添加到一个标签面板中。

“主视图”既是选项卡的标题,也是选项卡项的内容,没什么奇怪的。

如果我们也点击额外的视图,我们会得到这个:

我们可以看到一个选项卡变得可见,并且功能区中显示了额外的内容。如果我们在两个 tabpanel 选项卡之间切换,额外的 RibbonTab 只有在选择“extra view”时才可见。

现在,如果我们选择“extra view”选项卡,让额外的 RibbonTab 可见,然后单击文本框,使光标在其中闪烁,然后按几次 ctrl+TAB 以按选项卡顺序导航元素,我们很快就会再次选择标题为“额外视图”的选项卡。额外的 RibbonTab 看起来会与我们预期的不同。

唯一剩下的是选项卡文本“额外选项卡”,文本框不再存在。为什么不呢?

如果我们单击选项卡面板中的选项卡(显示“主视图”和“附加视图”,“附加选项卡”仅在选择“附加视图”时可见。这是预期的行为。但是,文本框和功能区制表符分隔符不再存在,这是意料之外的。

RibbonTab 的可见性绑定到 TabPanel 中选定的 TabItem 的类型,如果选项卡项的类型为 ExtraView,则使用转换器返回 Visibility.Visible,但如果类型为其他类型(如 MainView)则不返回。

RibbonTab 的 IsSelected 属性也绑定到选定的 tabitem,如果 tab item 是 ExtraView 类型,则使用返回 true 的转换器。

这如上所述,菜单选项卡的节目的最小示例是不仅仅是“额外标签”,所以重要的是,当TabPanels内容的类型正确时,它将被选中。我这样说是为了强调 IsSelected 是必需的(除了可见性)。

非常感谢任何帮助。

MainWindow.xaml:

<RibbonWindow x:Class="TestProblematicRibbons.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:test="clr-namespace:TestProblematicRibbons"
    xmlns:Converters="clr-namespace:TestProblematicRibbons.Converters"
    Height="300" Width="350">
  <RibbonWindow.DataContext>
    <test:MainWindowViewModel/>
  </RibbonWindow.DataContext>
  <RibbonWindow.Resources>
    <Converters:ExtraRibbonTabBooleanConverter x:Key="ExtraRibbonTabBoolean" />
    <Converters:ExtraRibbonTabVisibilityConverter x:Key="ExtraRibbonTabVisibility" />
  </RibbonWindow.Resources>
  <DockPanel>
    <Ribbon DockPanel.Dock="Top">
      <Ribbon.ApplicationMenu>
        <RibbonApplicationMenu>
          <RibbonApplicationMenuItem Header="main view"
            Command="Binding CreateMainViewCommand"/>
          <RibbonApplicationMenuItem Header="extra view"
            Command="Binding CreateExtraViewCommand"/>
        </RibbonApplicationMenu>
      </Ribbon.ApplicationMenu>

      <RibbonTab Header="extra tab"
          IsSelected="Binding SelectedTab, Mode=OneWay, Converter=StaticResource ExtraRibbonTabBoolean"
          Visibility="Binding SelectedTab, Mode=OneWay, Converter=StaticResource ExtraRibbonTabVisibility">
        <RibbonGroup>
          <RibbonTextBox />
        </RibbonGroup>
      </RibbonTab>
    </Ribbon>
    <TabControl
      ItemsSource="Binding Tabs" SelectedItem="Binding SelectedTab" />
  </DockPanel>
</RibbonWindow>

MainWindowModel.cs:

using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows.Input;
using ReactiveUI;

namespace TestProblematicRibbons

  public class MainWindowViewModel: ReactiveObject
  
    private ObservableCollection<TabItem> _tabs
      = new ObservableCollection<TabItem>();

    public ObservableCollection<TabItem> Tabs
    
      get  return _tabs; 
    

    private TabItem _SelectedTab;
    public TabItem SelectedTab
    
      get  return _SelectedTab; 
      set  this.RaiseAndSetIfChanged(x => x.SelectedTab, value); 
    

    public ICommand CreateMainViewCommand
     get  return new ActionCommand(CreateMainView);  

    public ICommand CreateExtraViewCommand
     get  return new ActionCommand(CreateExtraView);  

    private void CreateMainView()
    
      var view = new MainView();
      AddTab(view, "main view");
    

    private void CreateExtraView()
    
      var view = new ExtraView();
      AddTab(view, "extra view");
    

    private void AddTab(UserControl view, string header)
    
      var tab = new TabItem();
      tab.Header = header;
      tab.Content = view;
      _tabs.Add(tab);

      SelectedTab = tab;
    
  

ExtraRibbonTabBooleanConverter:

using System;
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Data;

namespace TestProblematicRibbons.Converters

  public class ExtraRibbonTabBooleanConverter: IValueConverter
  
    public object Convert
      (object value, Type targetType, object parameter, CultureInfo culture)
    
      var item = value as TabItem;

      return item != null && item.Content is ExtraView;
    

    public object ConvertBack
      (object value, Type targetType, object parameter, CultureInfo culture)
    
      throw new NotImplementedException();
    
  

ExtraRibbonTabVisibilityConverter:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace TestProblematicRibbons.Converters

  public class ExtraRibbonTabVisibilityConverter: IValueConverter
  
    public object Convert
      (object value, Type targetType, object parameter, CultureInfo culture)
    
      var item = value as TabItem;

      return item != null && item.Content is ExtraView
        ? Visibility.Visible
        : Visibility.Collapsed;
    

    public object ConvertBack
      (object value, Type targetType, object parameter, CultureInfo culture)
    
      throw new NotImplementedException();
    
  

MainView 和 ExtraView 只是两个带有标签的 UserControl:s,分别显示“主视图”和“额外视图”,所以在这里粘贴它们的代码没什么意义。

【问题讨论】:

我迷失了细节,所以必须对“太多细节”进行最后一票 请告诉我你在哪里迷路了 【参考方案1】:

在某些情况下,我通过手动实现绑定解决了我的问题。似乎不能完全依赖组合的绑定。他们显然可以互相打扰!

【讨论】:

以上是关于用于 RibbonTab 的 WPF IsSelected 绑定在 ctrl+tab 上停止工作的主要内容,如果未能解决你的问题,请参考以下文章

WPF:仅将使用“AddFontMemResourceEx”安装的字体用于进程

拉伸不适用于 WPF 模板化按钮

WPF API 可以安全地用于 WCF 服务吗?

Lync 客户端 SDK:FollowedRooms 不适用于 wpf

WPF 中的拖放不适用于 DataFormats.FileDrop

用于 C# 和 WPF 的高级全局键盘钩子,用于读取键盘楔形卡扫描仪