代码之家  ›  专栏  ›  技术社区  ›  touseefbsb

uwp文本框头仅在文本长度大于0时可见

  •  0
  • touseefbsb  · 技术社区  · 6 年前

    我试图编辑默认文本框的样式,这样每当它有文本时,标题都应该可见,当它为空时,占位符会显示出来,标题会消失。问题是,我必须在风格内做到这一点,而不创建自定义控件或用户控件,这就是为什么这对我来说有点棘手。

    我能够在整个控件(包括标题)周围设置边框,但到目前为止,我无法控制标题的可见性。我已经把样式放在一个单独的项目中,以下是代码。

    TextBox属性类

    public class TextBoxProperties : DependencyObject
    {
        public static bool GetInitialized(DependencyObject obj)
        {
            return (bool) obj.GetValue(InitializedProperty);
        }
    
        public static void SetInitialized(DependencyObject obj, bool value)
        {
            obj.SetValue(InitializedProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for Initialized.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty InitializedProperty =
            DependencyProperty.RegisterAttached("Initialized", typeof(bool), typeof(TextBoxProperties), new PropertyMetadata(false, OnInitialized));
    
        private static void OnInitialized(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var tb = (TextBox) d;
            tb.TextChanged += Tb_TextChanged;
            Update(tb);
        }
    
        private static void Tb_TextChanged(object sender, TextChangedEventArgs e)
        {
            Update((TextBox)sender);
        }
    
        private static void Update(TextBox tb) => SetShouldHeaderBeVisible(tb, tb.Text.Length > 0 ? Visibility.Visible : Visibility.Collapsed);
    
        public static Visibility GetShouldHeaderBeVisible(DependencyObject obj)
        {
            return (Visibility) obj.GetValue(ShouldHeaderBeVisibleProperty);
        }
    
        public static void SetShouldHeaderBeVisible(DependencyObject obj, Visibility value)
        {
            obj.SetValue(ShouldHeaderBeVisibleProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for ShouldHeaderBeVisible.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ShouldHeaderBeVisibleProperty =
            DependencyProperty.RegisterAttached("ShouldHeaderBeVisible", typeof(Visibility), typeof(TextBoxProperties), new PropertyMetadata(false));
    }
    

    文本框样式

    <Style TargetType="TextBox">
                <Setter Property="local:TextBoxProperties.Initialized" Value="true" />
                <Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
                <Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
                <Setter Property="Foreground" Value="{ThemeResource TextControlForeground}" />
                <Setter Property="Background" Value="{ThemeResource TextControlBackground}" />
                <Setter Property="BorderBrush" Value="{ThemeResource TextControlBorderBrush}" />
                <Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}" />
                <Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}" />
                <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
                <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
                <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto" />
                <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
                <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
                <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
                <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
                <Setter Property="HorizontalAlignment" Value="Stretch" />
                <Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}" />
                <Setter Property="UseSystemFocusVisuals" Value="{ThemeResource IsApplicationFocusVisualKindReveal}" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TextBox">
                            <Grid>
                                <Grid.Resources>
                                    <Style x:Name="DeleteButtonStyle" TargetType="Button">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="Button">
                                                    <Grid
                                                        x:Name="ButtonLayoutGrid"
                                                        Background="{ThemeResource TextControlButtonBackground}"
                                                        BorderBrush="{ThemeResource TextControlButtonBorderBrush}"
                                                        BorderThickness="{TemplateBinding BorderThickness}">
                                                        <TextBlock
                                                            x:Name="GlyphElement"
                                                            HorizontalAlignment="Center"
                                                            VerticalAlignment="Center"
                                                            AutomationProperties.AccessibilityView="Raw"
                                                            FontFamily="{ThemeResource SymbolThemeFontFamily}"
                                                            FontSize="12"
                                                            FontStyle="Normal"
                                                            Foreground="{ThemeResource TextControlButtonForeground}"
                                                            Text="&#xE10A;" />
                                                        <VisualStateManager.VisualStateGroups>
                                                            <VisualStateGroup x:Name="CommonStates">
                                                                <VisualState x:Name="Normal" />
                                                                <VisualState x:Name="PointerOver">
                                                                    <Storyboard>
                                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
                                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPointerOver}" />
                                                                        </ObjectAnimationUsingKeyFrames>
                                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="BorderBrush">
                                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPointerOver}" />
                                                                        </ObjectAnimationUsingKeyFrames>
                                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
                                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPointerOver}" />
                                                                        </ObjectAnimationUsingKeyFrames>
                                                                    </Storyboard>
                                                                </VisualState>
                                                                <VisualState x:Name="Pressed">
                                                                    <Storyboard>
                                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
                                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBackgroundPressed}" />
                                                                        </ObjectAnimationUsingKeyFrames>
                                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="BorderBrush">
                                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonBorderBrushPressed}" />
                                                                        </ObjectAnimationUsingKeyFrames>
                                                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
                                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlButtonForegroundPressed}" />
                                                                        </ObjectAnimationUsingKeyFrames>
                                                                    </Storyboard>
                                                                </VisualState>
                                                                <VisualState x:Name="Disabled">
                                                                    <Storyboard>
                                                                        <DoubleAnimation
                                                                            Storyboard.TargetName="ButtonLayoutGrid"
                                                                            Storyboard.TargetProperty="Opacity"
                                                                            To="0"
                                                                            Duration="0" />
                                                                    </Storyboard>
                                                                </VisualState>
                                                            </VisualStateGroup>
                                                        </VisualStateManager.VisualStateGroups>
                                                    </Grid>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </Grid.Resources>
    
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <Border
                                    x:Name="BorderElement"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Grid.ColumnSpan="2"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    Control.IsTemplateFocusTarget="True" />
                                <ContentPresenter
                                    x:Name="HeaderContentPresenter"
                                    Grid.Row="0"
                                    Grid.ColumnSpan="2"
                                    Margin="{StaticResource InputHeaderMargin}"
                                    x:DeferLoadStrategy="Lazy"
                                    Content="{TemplateBinding Header}"
                                    ContentTemplate="{TemplateBinding HeaderTemplate}"
                                    FontWeight="Normal"
                                    Foreground="{ThemeResource TextControlHeaderForeground}"
                                    TextWrapping="{TemplateBinding TextWrapping}"
                                    Visibility="{Binding local:TextBoxProperties.ShouldHeaderBeVisibleProperty, Mode=OneWay}" />
                                <ScrollViewer
                                    x:Name="ContentElement"
                                    Grid.Row="1"
                                    Margin="{TemplateBinding BorderThickness}"
                                    Padding="{TemplateBinding Padding}"
                                    AutomationProperties.AccessibilityView="Raw"
                                    HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                    HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                    IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                    IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                    IsTabStop="False"
                                    IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                    VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                    VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                    ZoomMode="Disabled" />
                                <TextBlock
                                    x:Name="PlaceholderTextContentPresenter"
                                    Grid.Row="1"
                                    Grid.ColumnSpan="2"
                                    Margin="{TemplateBinding BorderThickness}"
                                    Padding="{TemplateBinding Padding}"
                                    Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}"
                                    IsHitTestVisible="False"
                                    Text="{TemplateBinding Header}"
                                    TextAlignment="{TemplateBinding TextAlignment}"
                                    TextWrapping="{TemplateBinding TextWrapping}" />
                                <Button
                                    x:Name="DeleteButton"
                                    Grid.Row="1"
                                    Grid.Column="1"
                                    MinWidth="34"
                                    Margin="{ThemeResource HelperButtonThemePadding}"
                                    VerticalAlignment="Stretch"
                                    AutomationProperties.AccessibilityView="Raw"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    FontSize="{TemplateBinding FontSize}"
                                    IsTabStop="False"
                                    Style="{StaticResource DeleteButtonStyle}"
                                    Visibility="Collapsed" />
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
    
                                        <VisualState x:Name="Disabled">
    
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlHeaderForegroundDisabled}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundDisabled}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushDisabled}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundDisabled}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundDisabled}}" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Normal" />
    
                                        <VisualState x:Name="PointerOver">
    
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushPointerOver}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundPointerOver}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundPointerOver}}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundPointerOver}" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Focused">
    
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForegroundFocused}}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocused}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBorderBrushFocused}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlForegroundFocused}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="RequestedTheme">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Light" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="ButtonStates">
                                        <VisualState x:Name="ButtonVisible">
    
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
                                                    <DiscreteObjectKeyFrame KeyTime="0">
                                                        <DiscreteObjectKeyFrame.Value>
                                                            <Visibility>Visible</Visibility>
                                                        </DiscreteObjectKeyFrame.Value>
                                                    </DiscreteObjectKeyFrame>
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="ButtonCollapsed" />
                                    </VisualStateGroup>
    
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    
    0 回复  |  直到 6 年前
        1
  •  1
  •   ardget    6 年前

    可能尝试直接将绑定应用于HeaderContentPresenter。可见性不会成功,因为该属性是由TextBox编程控制的。因此,将HeaderContentPresenter放在另一个边框中并更改其可见性。

    <Border Grid.Row="0" Grid.ColumnSpan="2" Visibility="{TemplateBinding local:TextBoxProperties.ShouldHeaderBeVisible}">
        <ContentPresenter
            x:Name="HeaderContentPresenter"
            Margin="{StaticResource InputHeaderMargin}"
            x:DeferLoadStrategy="Lazy"
            Content="{TemplateBinding Header}"
            ContentTemplate="{TemplateBinding HeaderTemplate}"
            FontWeight="Normal"
            Foreground="{ThemeResource TextControlHeaderForeground}"
            TextWrapping="{TemplateBinding TextWrapping}"
            Visibility="Collapsed" />
    </Border>
    
    推荐文章