显示子内容时如何隐藏父控件?

时间:2018-11-20 10:53:46

标签: wpf visibility parent children

如何隐藏父项TabControl,直到单击其选项卡之一中的子项为止?显然,我需要让孩子可见,以便用户能够单击它。到目前为止,我唯一想出的办法就是破解……我在TabControl上方显示了一个额外的子项,然后将其隐藏并显示{{1 }}。这是我的技巧:

XAML:

TabControl

后面的代码:

<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; } } }

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

1 个答案:

答案 0 :(得分:2)

如@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>

Tab控件具有2个触发器:当有人单击BorderBrush时将TabControl设置为黑色,而当MousePointer离开Transparent时将其设置为TabControl。这两个人处理TabControl本身的可见性。注意:如果您的TriggerBackground后的Color不同,则添加其他TabControl

TabItem有一个Trigger绑定到Color TabControl的{​​{1}}。如果Border为黑色,请显示Color中的Header,否则将其隐藏。

enter image description here