如何隐藏 WPF 控件的一部分

Posted

技术标签:

【中文标题】如何隐藏 WPF 控件的一部分【英文标题】:How to hide a part of a WPF control 【发布时间】:2011-06-12 16:20:15 【问题描述】:

是否可以隐藏 WPF 控件的一部分?根据MSDN,.NET 4 有一个呈现 4 个部分的 DatePicker。是否可以隐藏(在我的情况下)TextBox 部分(可能命名为 PART_TextBox)?

我已经看到了完全设置 DatePicker 样式的示例,它涉及很多 XAML,而我只想隐藏控件的一部分。

【问题讨论】:

【参考方案1】:

好吧,我有一个解决方案:)

class MyDateTimePicker : DatePicker

    public override void OnApplyTemplate()
    
        base.OnApplyTemplate();

        var textBox = this.Template.FindName("PART_TextBox", this) as UIElement;
        if (textBox != null)
        
            textBox.Visibility = Visibility.Hidden;
        
    

【讨论】:

虽然我相信所有答案都是有效的,但由于继承,这是最简单的,同时仍然可以重用。这花了我 1 分钟来实施。谢谢!【参考方案2】:

您可以在 XAML 中使用行为和我写的 TemplatePartAction 来完成这一切:

    <DatePicker>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <local:TemplatePartAction TemplatePartName="TextBox">
                    <ei:ChangePropertyAction PropertyName="Visibility" Value="Collapsed"/>
                </local:TemplatePartAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </DatePicker>

这里是TemplatePart 功能:

public class TemplatePartHelper<T> where T : IAttachedObject

    public IAttachedObject Parent  get; set; 
    public List<T> Children  get; private set; 
    public string Name  get; set; 
    public Control TemplatePart  get; set; 

    public TemplatePartHelper(IAttachedObject parent)
    
        Parent = parent;
        Children = new List<T>();
    

    public void AssociateChildren()
    
        if (TemplatePart != null)
            return;
        var control = Parent.AssociatedObject as Control;
        var template = control.Template;
        if (template == null)
            return;
        var partName = "PART_" + Name;
        TemplatePart = template.FindName(partName, control) as Control;
        if (TemplatePart == null)
            return;
        foreach (var child in Children)
            child.Attach(TemplatePart);
    


[ContentProperty("Behaviors")]
public class TemplatePartBehavior : Behavior<Control>

    public TemplatePartHelper<Behavior> Helper  get; private set; 
    public List<Behavior> Behaviors  get  return Helper.Children;  
    public string TemplatePartName  get  return Helper.Name;  set  Helper.Name = value;  

    public TemplatePartBehavior()
    
        Helper = new TemplatePartHelper<Behavior>(this);
    

    protected override void OnAttached()
    
        AssociatedObject.Initialized += (s, e) => Helper.AssociateChildren();
        AssociatedObject.Loaded += (s, e) => Helper.AssociateChildren();
    


[ContentProperty("Actions")]
public class TemplatePartAction : TriggerAction<Control>

    public TemplatePartHelper<TriggerAction> Helper  get; private set; 
    public List<TriggerAction> Actions  get  return Helper.Children;  
    public string TemplatePartName  get  return Helper.Name;  set  Helper.Name = value;  

    public TemplatePartAction()
    
        Helper = new TemplatePartHelper<TriggerAction>(this);
    

    protected override void OnAttached()
    
        AssociatedObject.Loaded += (s, e) => Helper.AssociateChildren();
    

    protected override void Invoke(object parameter)
    
        foreach (var action in Actions)
        
            if (action.IsEnabled)
            
                var methodInfo = typeof(TriggerAction).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[]  typeof(object) , null);
                methodInfo.Invoke(action, new object[]  parameter );
            
        
    

如果您不熟悉行为,请安装 Expression Blend 4 SDK 并添加以下命名空间:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

并将System.Windows.InteractivityMicrosoft.Expression.Interactions 添加到您的项目中。

【讨论】:

【参考方案3】:

为什么不在默认样式中将Visibility="Collapsed"添加到相关的TextBox

<Style TargetType="controls:DatePicker">
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="Background" Value="#FFFFFFFF" />
    <Setter Property="Padding" Value="2" />
    <Setter Property="SelectionBackground" Value="#FF444444" />
    <Setter Property="BorderBrush">
        <Setter.Value>
            <LinearGradientBrush EndPoint=".5,0" StartPoint=".5,1">
                <GradientStop Color="#FF617584" Offset="0" />
                <GradientStop Color="#FF718597" Offset="0.375" />
                <GradientStop Color="#FF8399A9" Offset="0.375" />
                <GradientStop Color="#FFA3AEB9" Offset="1" />
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:DatePicker">
                <Grid x:Name="Root">
                    <Grid.Resources>
                        <!-- Main DatePicker Brushes -->
                        <SolidColorBrush x:Key="DisabledBrush" Color="#8CFFFFFF" />

                        <!-- Button Template -->
                        <ControlTemplate x:Key="DropDownButtonTemplate" TargetType="Button">
                            <Grid FlowDirection="LeftToRight">
                                <vsm:VisualStateManager.VisualStateGroups>
                                    <vsm:VisualStateGroup x:Name="CommonStates">
                                        <vsm:VisualStateGroup.Transitions>
                                            <vsm:VisualTransition GeneratedDuration="0" />
                                            <vsm:VisualTransition To="MouseOver" GeneratedDuration="0:0:0.1" />
                                            <vsm:VisualTransition To="Pressed" GeneratedDuration="0:0:0.1" />
                                        </vsm:VisualStateGroup.Transitions>
                                        <vsm:VisualState x:Name="Normal" />
                                        <vsm:VisualState x:Name="MouseOver">
                                            <Storyboard>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#FF448DCA" />
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#7FFFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#CCFFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#F2FFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </vsm:VisualState>
                                        <vsm:VisualState x:Name="Pressed">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#FF448DCA" />
                                                </ColorAnimationUsingKeyFrames>
                                                <DoubleAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="Highlight" Storyboard.TargetProperty="(UIElement.Opacity)">
                                                    <SplineDoubleKeyFrame KeyTime="0" Value="1" />
                                                </DoubleAnimationUsingKeyFrames>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#EAFFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#C6FFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#6BFFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                                <ColorAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
                                                    <SplineColorKeyFrame KeyTime="0" Value="#F4FFFFFF" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </vsm:VisualState>
                                        <vsm:VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <DoubleAnimationUsingKeyFrames BeginTime="0" Duration="00:00:00.001" Storyboard.TargetName="DisabledVisual" Storyboard.TargetProperty="(UIElement.Opacity)">
                                                    <SplineDoubleKeyFrame KeyTime="0" Value="1" />
                                                </DoubleAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </vsm:VisualState>
                                    </vsm:VisualStateGroup>
                                </vsm:VisualStateManager.VisualStateGroups>

                                <!--Start UI-->
                                <Grid Height="18" Width="19" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" Background="#11FFFFFF">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="20*" />
                                        <ColumnDefinition Width="20*" />
                                        <ColumnDefinition Width="20*" />
                                        <ColumnDefinition Width="20*" />
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="23*" />
                                        <RowDefinition Height="19*" />
                                        <RowDefinition Height="19*" />
                                        <RowDefinition Height="19*" />
                                    </Grid.RowDefinitions>
                                    <Border Margin="-1" Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="4" BorderThickness="1" BorderBrush="#FF6DBDD1" Opacity="0" CornerRadius="0,0,1,1" x:Name="Highlight" />
                                    <Border x:Name="Background" Margin="0,-1,0,0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" BorderThickness="1" BorderBrush="#FFFFFFFF" Opacity="1" CornerRadius=".5" Background="#FF1F3B53" />
                                    <Border x:Name="BackgroundGradient" Margin="0,-1,0,0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" BorderThickness="1" BorderBrush="#BF000000" Opacity="1" CornerRadius=".5">
                                        <Border.Background>
                                            <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                                                <GradientStop Color="#FFFFFFFF" Offset="0" />
                                                <GradientStop Color="#F9FFFFFF" Offset="0.375" />
                                                <GradientStop Color="#E5FFFFFF" Offset="0.625" />
                                                <GradientStop Color="#C6FFFFFF" Offset="1" />
                                            </LinearGradientBrush>
                                        </Border.Background>
                                    </Border>
                                    <Rectangle Grid.ColumnSpan="4" Grid.RowSpan="1" StrokeThickness="1">
                                        <Rectangle.Stroke>
                                            <LinearGradientBrush EndPoint="0.48,-1" StartPoint="0.48,1.25">
                                                <GradientStop Color="#FF494949" />
                                                <GradientStop Color="#FF9F9F9F" Offset="1" />
                                            </LinearGradientBrush>
                                        </Rectangle.Stroke>
                                        <Rectangle.Fill>
                                            <LinearGradientBrush EndPoint="0.3,-1.1" StartPoint="0.46,1.6">
                                                <GradientStop Color="#FF4084BD" />
                                                <GradientStop Color="#FFAFCFEA" Offset="1" />
                                            </LinearGradientBrush>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                    <Path HorizontalAlignment="Center" Margin="4,3,4,3" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Grid.Column="0" Grid.Row="1" Fill="#FF2F2F2F" Stretch="Fill" Data="M11.426758,8.4305077 L11.749023,8.4305077 L11.749023,16.331387 L10.674805,16.331387 L10.674805,10.299648 L9.0742188,11.298672 L9.0742188,10.294277 C9.4788408,10.090176 9.9094238,9.8090878 10.365967,9.4510155 C10.82251,9.0929432 11.176106,8.7527733 11.426758,8.4305077 z M14.65086,8.4305077 L18.566387,8.4305077 L18.566387,9.3435936 L15.671368,9.3435936 L15.671368,11.255703 C15.936341,11.058764 16.27293,10.960293 16.681133,10.960293 C17.411602,10.960293 17.969301,11.178717 18.354229,11.615566 C18.739157,12.052416 18.931622,12.673672 18.931622,13.479336 C18.931622,15.452317 18.052553,16.438808 16.294415,16.438808 C15.560365,16.438808 14.951641,16.234707 14.468243,15.826504 L14.881817,14.929531 C15.368796,15.326992 15.837872,15.525723 16.289043,15.525723 C17.298809,15.525723 17.803692,14.895514 17.803692,13.635098 C17.803692,12.460618 17.305971,11.873379 16.310528,11.873379 C15.83071,11.873379 15.399232,12.079271 15.016094,12.491055 L14.65086,12.238613 z" Grid.ColumnSpan="4" Grid.RowSpan="3" />
                                    <Ellipse HorizontalAlignment="Center" VerticalAlignment="Center" Fill="#FFFFFFFF" StrokeThickness="0" Grid.ColumnSpan="4" Width="3" Height="3" />
                                    <Border Grid.ColumnSpan="4" Grid.Row="0" Grid.RowSpan="4" BorderThickness="1" BorderBrush="#B2FFFFFF" Opacity="0" CornerRadius="0,0,.5,.5" x:Name="DisabledVisual" />
                                </Grid>
                                <!--End UI-->
                            </Grid>
                        </ControlTemplate>
                    </Grid.Resources>
                    <vsm:VisualStateManager.VisualStateGroups>
                        <vsm:VisualStateGroup x:Name="CommonStates">
                            <vsm:VisualState x:Name="Normal" />
                            <vsm:VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="DisabledVisual" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
                                </Storyboard>
                            </vsm:VisualState>
                        </vsm:VisualStateGroup>
                        <vsm:VisualStateGroup x:Name="ValidationStates">
                            <vsm:VisualState x:Name="Valid" />
                            <vsm:VisualState x:Name="InvalidUnfocused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </vsm:VisualState>
                            <vsm:VisualState x:Name="InvalidFocused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <system:Boolean>True</system:Boolean>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </vsm:VisualState>
                        </vsm:VisualStateGroup>
                    </vsm:VisualStateManager.VisualStateGroups>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <controlsPrimitives:DatePickerTextBox x:Name="TextBox" SelectionBackground="TemplateBinding SelectionBackground" Background="TemplateBinding Background" BorderBrush="TemplateBinding BorderBrush" BorderThickness="TemplateBinding BorderThickness" Padding="TemplateBinding Padding" Grid.Column="0" Visibility="Collapsed" />
                    <Border x:Name="ValidationErrorElement" Grid.Column="0" BorderThickness="1" CornerRadius="1" BorderBrush="#FFDB000C" Visibility="Collapsed">
                        <ToolTipService.ToolTip>
                            <ToolTip x:Name="validationTooltip" Template="StaticResource CommonValidationToolTipTemplate" Placement="Right" PlacementTarget="Binding ElementName=TextBox" DataContext="Binding RelativeSource=RelativeSource TemplatedParent">
                                <ToolTip.Triggers>
                                    <EventTrigger RoutedEvent="Canvas.Loaded">
                                        <EventTrigger.Actions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <system:Boolean>true</system:Boolean>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </EventTrigger.Actions>
                                    </EventTrigger>
                                </ToolTip.Triggers>
                            </ToolTip>
                        </ToolTipService.ToolTip>
                        <Grid Width="12" Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Background="Transparent">
                            <Path Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" />
                            <Path Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#FFFFFF" />
                        </Grid>
                    </Border>                        
                    <Button x:Name="Button" Template="StaticResource DropDownButtonTemplate" Grid.Column="1" Width="20" Foreground="TemplateBinding Foreground" BorderBrush="TemplateBinding BorderBrush" BorderThickness="TemplateBinding BorderThickness" Margin="2,0,2,0" />
                    <Grid x:Name="DisabledVisual" Opacity="0" IsHitTestVisible="False" Grid.ColumnSpan="2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Rectangle RadiusX="1" RadiusY="1" Fill="#8CFFFFFF" />
                        <Rectangle RadiusX="1" RadiusY="1" Fill="#8CFFFFFF" Grid.Column="1" Height="18" Width="19" Margin="2,0,2,0" />
                    </Grid>
                    <Popup x:Name="Popup" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

【讨论】:

【参考方案4】:

您可以将默认的 Button Style 更改为 Visibility.Collapsed。例如,如果您想在 Grid 中隐藏 2 个 DatePicker 的按钮,您可以执行以下操作:

<Grid.Resources>
     <Style TargetType="x:Type Button">
           <Setter Property="Visibility" Value="Collapsed"/>
     </Style>
</Grid.Resources>

仅 XAML 解决方案,无继承 ...

【讨论】:

以上是关于如何隐藏 WPF 控件的一部分的主要内容,如果未能解决你的问题,请参考以下文章

WPF如何把隐藏控件显示出来

裁剪 WPF 控件

WPF ComboBox控件隐藏倒三角

如何防止屏幕阅读器/旁白阅读隐藏在 WPF 中的控件?

如何隐藏控件textblock

WPF中控件的显示与隐藏