如何在显示 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;
}
}
}
为简单起见,我已将内容更改为纯 Rectangle
s。
如何改善这种情况?我不喜欢复制 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
本身的可见性。注意:如果您的 Background
与 TabControl
后面的 Color
不同,请添加额外的 Trigger
。
TabItem
有一个 Trigger
绑定到 TabControl
Border
的 Color
。如果 Color
是黑色,显示 TabItem
的 Header
否则,隐藏它们。
如何隐藏 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;
}
}
}
为简单起见,我已将内容更改为纯 Rectangle
s。
如何改善这种情况?我不喜欢复制 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
本身的可见性。注意:如果您的 Background
与 TabControl
后面的 Color
不同,请添加额外的 Trigger
。
TabItem
有一个 Trigger
绑定到 TabControl
Border
的 Color
。如果 Color
是黑色,显示 TabItem
的 Header
否则,隐藏它们。