【问题标题】:WPF TabControl - Select different tab when TabItem Visibility changesWPF TabControl - 当 TabItem 可见性更改时选择不同的选项卡
【发布时间】:2011-04-04 06:26:57
【问题描述】:

我在由 ViewModel 支持的 UserControl 上有一个 TabControl,其中一个选项卡项的 Visibility 绑定到 ViewModel 上的一个属性。

<TabControl x:Name="myTabControl">
    <TabItem Header="Tab 1" />
    <TabItem Header="Tab 2" Visibility="{Binding HasData, Converter={StaticResource boolToVisibilityConverter}}"/>
</TabControl>

TabItemVisibility 发生变化时,它会折叠(隐藏)TabItem 标头,但会继续显示其内容。

我希望TabControl 在另一个标签被隐藏时切换到可见标签,我有点惊讶地发现它不会自动发生。

将事件处理程序附加到TabControlSelectionChanged 事件表明TabItem.IsSelected(和TabControl.SelectedItem)甚至不会在TabItem.Visibility 更改时受到影响(这是一个错误吗?!)。

我已经尝试了两个属性触发器

    <!-- This doesn't compile because of TargetName on the Setter, think you can only use it in Control Templates.
         I don't know how to refer to the parent TabControl from within the TabItem style. -->
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
            <Style.Triggers>
                <Trigger Property="Visibility" Value="Collapsed">
                    <Setter TargetName="myTabControl" Property="SelectedIndex" Value="0" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </TabControl.ItemContainerStyle>

和一个数据触发器

    <!-- This doesn't quite work, it affects the Visibility of the TabItem's content too -->
    <TabControl.Style>
        <Style TargetType="{x:Type TabControl}" BasedOn="{StaticResource {x:Type TabControl}}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=SelectedItem.Visibility, ElementName=tabControl}" 
                             Value="Collapsed">
                    <Setter Property="SelectedIndex" Value="0" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TabControl.Style>

我无法让触发器工作,也没有我可以处理的 VisibilityChanged 事件,所以我有点卡住了,希望能得到一些帮助。

【问题讨论】:

    标签: wpf


    【解决方案1】:

    TabItem 类有一个您可以使用的 IsVisibleChanged 事件。

    【讨论】:

    • 啊,这样就行了! (+1) 不知道为什么我没有早点发现它——我猜 MSDN 当时一定已经过滤掉了继承的属性。我将推迟标记这是答案,只是想看看是否有人有非代码隐藏的建议,但非常感谢。
    【解决方案2】:

    将 TabControl 的 SelectedIndex 绑定到一个属性。并将此属性的值更改为您希望在将可见性更改为标签项折叠时显示的标签索引。

    【讨论】:

      【解决方案3】:

      您可以将此事件处理程序添加到后面的代码中。它将首先测试您的控件以及由于绑定导致的选项卡可见性更改。

      当然,而不是这样做 OnLoaded 将其放入附加属性中是完全有意义的。 (自动选择?) 。代码是一样的。您首先被调用并将事件附加到 IsVisibleChanged。然后唯一的技巧是使用 lambda(参数绑定)将 TabControl 实例放入事件回调中。我发布了这个解决方案,因为它更短。

      private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
      {
          var tabControl = (TabControl) sender;
          // register visibility changed to react on changes
          foreach (TabItem item in tabControl.Items)
          {
              item.IsVisibleChanged += (mSender, ev) => item_IsVisibleChanged(mSender, ev, tabControl);
          }
          // if current selected tab is invisible, find and select first visible one.
          if (!((TabItem) tabControl.SelectedItem).IsVisible)
          {
              foreach (TabItem item in tabControl.Items)
              {
                  if (item.IsVisible)
                  {
                      tabControl.SelectedItem = item;
                      return;
                  }
              }
          }
      }
      
      private static void item_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e, TabControl tabControl)
      {
          // just became IsVisible = false
          if ((bool)e.NewValue == false)
          {
              if (tabControl == null) return;
              ItemCollection items = tabControl.Items;
              foreach (UIElement item in items)
              {
                  if (item.IsVisible)
                  {
                      tabControl.SelectedItem = item;
                      return;
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-03
        • 1970-01-01
        • 1970-01-01
        • 2015-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多