如何在显示 child 内容的同时隐藏 parent 控件?

How to hide parent control while showing child content?

如何隐藏 parent TabControl 直到其选项卡之一中的 child 被点击?显然,我需要 child 对用户可见才能单击它。到目前为止,我想出的唯一一件事就是有点黑客...我在 TabControl 的顶部显示了一个额外的 child 项目,然后将其隐藏并显示单击 TabControl。这是我的技巧:

XAML:

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="MainWindow" Height="500" Width="600" 
        PreviewMouseLeftButtonUp="Grid_PreviewMouseLeftButtonUp">
    <Window.Resources>
        <Style TargetType="{x:Type Rectangle}">
            <Setter Property="Width" Value="300" />
            <Setter Property="Height" Value="250" />
        </Style>
    </Window.Resources>
    <Grid>
        <TabControl Name="TabControl" Width="350" Height="300">
            <TabItem Header="Original">
                <Rectangle Fill="Red" />
            </TabItem>
            <TabItem Header="Modified">
                <Rectangle Fill="Blue" />
            </TabItem>
            <TabControl.Style>
                <Style TargetType="{x:Type TabControl}">
                    <Setter Property="Visibility" Value="Collapsed" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsTabControlVisible}" 
                            Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TabControl.Style>
        </TabControl>
        <Rectangle Fill="Red" Margin="0,22,0,0"
            PreviewMouseLeftButtonUp="Rectangle_PreviewMouseLeftButtonUp">
            <Rectangle.Style>
                <Style TargetType="{x:Type Rectangle}" 
                    BasedOn="{StaticResource {x:Type Rectangle}}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsTabControlVisible}" 
                            Value="True">
                            <Setter Property="Visibility" Value="Collapsed" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Rectangle.Style>
        </Rectangle>
    </Grid>
</Window>

后面的代码:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        public static readonly DependencyProperty IsTabControlVisibleProperty = 
            DependencyProperty.Register(nameof(IsTabControlVisible), typeof(bool), 
            typeof(MainWindow), null);

        public bool IsTabControlVisible
        {
            get { return (bool)GetValue(IsTabControlVisibleProperty); }
            set { SetValue(IsTabControlVisibleProperty, value); }
        }

        private void Rectangle_PreviewMouseLeftButtonUp(object sender, 
            MouseButtonEventArgs e)
        {
            IsTabControlVisible = true;
        }

        private void Grid_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!TabControl.IsMouseOver) IsTabControlVisible = false;
        }
    }
}

为简单起见,我已将内容更改为纯 Rectangles。

如何改善这种情况?我不喜欢复制 child 内容来完成这项工作的想法。有没有人有更好的解决方案?

正如@XAMIMAX 提到的那样,您可以隐藏 TabControl 但不能隐藏它的 Opacity (因为将其设置为 0 也会隐藏子项)。以下 XAML 只是通过隐藏除子元素之外的所有元素来快速且粗略地证明概念:

<TabControl Name="TabControl" Width="350" Height="300" BorderBrush="Transparent">
    <!-- Content of the Tabcontrol -->
    <TabItem Header="Original">
        <Rectangle Fill="Red" />
    </TabItem>
    <TabItem Header="Modified" >
        <Rectangle Fill="Blue" />
    </TabItem>

    <!-- Triggers for the TabControl -->
    <TabControl.Triggers>
        <!-- Set Borderbrush to Black when tab is clicked -->
        <EventTrigger RoutedEvent="MouseDown">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(BorderBrush).(SolidColorBrush.Color)">
                            <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Colors.Black}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
        <!-- Reset BorderBrush when Mouse leaves the TabControl (choose wathever condition you like to hide the tabs) -->
        <EventTrigger RoutedEvent="MouseLeave">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(BorderBrush).(SolidColorBrush.Color)">
                            <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Colors.Transparent}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </TabControl.Triggers>

    <!-- Set "Style" of Container -->
    <TabControl.ItemContainerStyle>
        <Style TargetType="{x:Type TabItem}">
            <!-- Hide Header -->
            <Setter Property="Visibility" Value="Hidden"/>
            <!-- Show header when Border of parent is Black (you can choose a different Property if you like) -->
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabControl}}, Path=(BorderBrush).(SolidColorBrush.Color)}" Value="Black">
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TabControl.ItemContainerStyle>
</TabControl>

Tabcontrol 有 2 个触发器:当有人点击 TabControl 时将 BorderBrush 设置为黑色,当鼠标指针离开 TabControl 时将其设置为 Transparent。这两个处理 TabControl 本身的可见性。注意:如果您的 BackgroundTabControl 后面的 Color 不同,请添加额外的 Trigger

TabItem 有一个 Trigger 绑定到 TabControl BorderColor。如果 Color 是黑色,显示 TabItemHeader 否则,隐藏它们。