WPF TextBox中的帮助文本在第一次输入后消失 - 水印,XAML方式

Chr*_*ian 3 wpf xaml textbox

在WPF TextBox中,我想提供在第一次输入后消失的描述.这应该为用户提供一些帮助,他应该在文本字段中输入什么.

可以使用Label在给定的TextBox上方显示文本.我对一个例子感兴趣,但找不到任何例子.理想情况下,解决方案仅适用于XAML.

Chr*_*ian 8

我根据anvarbek raupov提供的链接整理了一个完整的例子(http://blogs.windowsclient.net/swt62/archive/2009/05/10/wpf-textbox-watermark-the-easy-way.aspx) .诀窍是在文本框上方添加一个附加标签,仅当文本框的内容为空且未聚焦时才会显示.该条件在XAML中使用触发器实现.我的示例样式使文本框样式与正常行为保持不变.

该示例包含注释资源字典(WatermarkResource.xaml)和带有普通文本框和带水印文本框的MainWindow.xaml.后面的代码只进行初始化,并且与向导生成的WPF应用程序保持不变.

这是WatermarkResource.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- Add TargetType="{x:Type TextBox}" to make this style the default for all TextBoxes. -->
    <Style x:Key="WatermarkedTextBox" >
        <Setter Property="Control.Template" >
            <Setter.Value>
                <ControlTemplate TargetType="TextBox" >
                    <!-- Template derived from Default TextBoxBase. -->
                    <!-- Added the Label InternalWatermarkLabel together with the surrounding Grid. -->
                    <Grid>
                        <mwt:ListBoxChrome Name="Bd"
                                           Background="{TemplateBinding Panel.Background}" 
                                           BorderBrush="{TemplateBinding Border.BorderBrush}"
                                           BorderThickness="{TemplateBinding Border.BorderThickness}"
                                           RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}" 
                                           RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}" 
                                           SnapsToDevicePixels="True">
                            <ScrollViewer Name="PART_ContentHost"
                                          SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
                                          />
                        </mwt:ListBoxChrome>
                        <Label x:Name="InternalWatermarkLabel" 
                               Content="{TemplateBinding Tag}" 
                               Visibility="Collapsed" Focusable="False"
                               Foreground="Silver"
                               Background="Transparent"
                               />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <!-- The multitrigger is responsible for showing and hiding the watermark. -->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsFocused" Value="False" />
                                <Condition Property="Text" Value="" />
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="Visibility" TargetName="InternalWatermarkLabel"
                                        Value="Visible" />
                            </MultiTrigger.Setters>
                        </MultiTrigger>
                        <!-- This trigger mimics the default behavior. -->
                        <Trigger Property="UIElement.IsEnabled" Value="False" >
                            <Setter Property="Panel.Background" TargetName="Bd"
                                    Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                            <Setter Property="TextElement.Foreground"
                                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)

这是MainWindow.xaml:

<Window x:Class="WpfWatermark.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Watermark, the XAML way" Height="120" Width="400" >
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="WatermarkResource.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Content="Textbox with Watermark:" />
        <!-- The FrameworkElement.Tag Property of .NET 4 is used to store the -->
        <!-- watermark information as the custom information about this element. -->
        <TextBox Grid.Row="0" Grid.Column="1" 
                 Tag="This is the Watermark Text." 
                 Style="{StaticResource WatermarkedTextBox}" 
                 />
        <Label Grid.Row="1" Content="A normal Textbox:" />
        <TextBox Grid.Row="1" Grid.Column="1" />
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

这是具有可见水印的正在运行的应用程序的屏幕截图

水印,XAML方式

这是一些文本,隐藏了水印

隐藏的水印