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

Posted

技术标签:

【中文标题】如何在显示子内容时隐藏父控件?【英文标题】:How to hide parent control while showing child content? 【发布时间】:2019-04-22 19:17:40 【问题描述】:

如何隐藏父 TabControl,直到其中一个标签中的子被点击?显然,我需要让用户看到孩子才能点击它。到目前为止,我设法想出的唯一一件事就是有点破解......我在TabControl 的顶部显示了一个额外的子项,然后将其隐藏并在单击时显示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。

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

【问题讨论】:

请再读一遍我的问题...我说过 我不喜欢复制子内容来完成这项工作的想法。有没有人有更好的解决方案?我现在正在尝试Adorners,这是实现我所追求的一种可能的方式。 如果不是隐藏TabControl,而是改变它的不透明度怎么办?然后你必须控制孩子的不透明度。 你去@mm8,一位初级会员已经为你回答了你的问题。通过使用其不透明度,可以在其父元素不存在时显示子元素。感谢您问我与 SO 社区相同的问题……非常有帮助。 ;) 也谢谢你,@XAMlMAX。 【参考方案1】:

正如@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 不同,请添加额外的Triggers。

TabItem 有一个Trigger 绑定到ColorTabControl Border。如果Color 是黑色的,则显示HeaderHeader,否则隐藏它们。

【讨论】:

这是一个有趣的想法@LittleBit。它实际上可能对我有用......我现在正在尝试,我会回复你。 是的,这对我有用。谢谢。继续努力,你会在这个网站上做得很好。 :)

以上是关于如何在显示子内容时隐藏父控件?的主要内容,如果未能解决你的问题,请参考以下文章

Delphi中子窗体如何继承父窗体

c#如何把子窗体的值传给父窗体?

隐藏超出父元素的子元素的部分:overflow

C#中子窗体操作父窗体的变量

Delphi_子窗体继承父窗体后如何显示父窗体上的控件

js 关闭子窗体时如何刷新父窗体