WPF TabControl - 当TabItem可见性更改时选择不同的选项卡

时间:2010-08-26 13:04:39

标签: wpf

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

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

Visibility的{​​{1}}发生更改时,它会折叠(隐藏)TabItem标题,但会继续显示其内容。

我希望TabItem 在隐藏其他标签时切换到可见标签,并且有点惊讶地发现它不会自动发生。

将事件处理程序附加到TabControl的{​​{1}}事件会显示SelectionChanged(和TabControl)在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> 事件,因此我有点卡住并会感激一些帮助。

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

将TabControl的SelectedIndex绑定到属性。并且只要您将标签项的可见性更改为标签项的可见性,就可以将此属性的值更改为要显示的标签索引。

答案 2 :(得分:1)

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

当然,将它放入附加的Property中是完全合理的,而不是这样做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;
            }
        }
    }
}