Текст справки в WPF TextBox, который исчезает после первого ввода - Водяной знак, способ XAML - PullRequest
3 голосов
/ 08 апреля 2011

В текстовом поле WPF я хотел бы предоставить описание, которое исчезает после первого ввода.Это должно немного помочь пользователю, что он должен ввести в текстовое поле.

Текст может отображаться над заданным TextBox с помощью метки.Я заинтересован в примере , но не смог найти ни одного.В идеале решение - только XAML.

Ответы [ 4 ]

8 голосов
/ 11 апреля 2011

Я собрал полный пример на основе предоставленной ссылки от Анварбека Раупова (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>

И это 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>

Это скриншот запущенного приложения с видимым водяным знаком

Watermark, the XAML way

, и это с некоторым текстомгде водяной знак скрыт

hidden Watermark

3 голосов
/ 07 ноября 2012

.Net 4 Версия христианского решения, также не требуется аэробиблиотека:

<ControlTemplate TargetType="{x:Type TextBox}">
    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
        <Grid>
            <ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>

            <TextBlock x:Name="InternalWatermarkLabel" 
                       Text="{TemplateBinding Tag}" 
                       Visibility="Collapsed" Focusable="False"
                       VerticalAlignment="Top" Margin=" 5 1 0 0"
                       Foreground="Silver"
                       Background="Transparent"/>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <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>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Opacity" TargetName="border" Value="0.56"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocused" Value="True">
            <Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
0 голосов
/ 12 сентября 2018

Для всех, кто может быть заинтересован в этом вопросе, проверьте дизайн материала (http://materialdesigninxaml.net/).

С этой библиотекой это действительно просто:

<TextBox
x:Name="SuggestedTextBox"
materialDesign:HintAssist.Hint="My suggestion" />
0 голосов
/ 10 ноября 2014

Вот решение только для XAML, использующее довольно простые «механизмы».

Я ни в коем случае не эксперт по XAML. Вероятно, есть лучшие и / или более элегантные способы сделать это, но это то, что я получил, попробовав и объединив вещи, которые я нашел на этом сайте.

Я думал, что это довольно прямо, явно, и это может быть полезно для некоторых ...

Не стесняйтесь комментировать любые вопросы или вещи, которые можно сделать лучше.

                <Grid>
                <TextBox Name="TheField"
                         HorizontalAlignment="Center"
                         VerticalAlignment="Center"
                         MinWidth="170"
                         Background="Transparent"
                         Foreground="Black"
                         Margin="5,2,5,2"
                         BorderThickness="0"
                         FontSize="10"
                         Text="{Binding THE_BOUNDED_PROPERTY, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox HorizontalAlignment="Center"
                         VerticalAlignment="Center"
                         MinWidth="170"
                         Foreground="#FF808080"
                         Margin="5,2,5,2"
                         IsHitTestVisible="False"
                         BorderThickness="0"
                         FontStyle="Italic"
                         FontSize="10"
                         Text="THE DEFAULT TEXT">
                    <TextBox.Style>
                        <Style TargetType="TextBox">
                            <Style.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding ElementName=TheField, Path=IsKeyboardFocusWithin}" Value="False"/>
                                        <Condition Binding="{Binding ElementName=TheField, Path=Text.IsEmpty}" Value="True"/>
                                    </MultiDataTrigger.Conditions>
                                    <Setter Property="Visibility" Value="Visible"/>
                                </MultiDataTrigger>
                                <DataTrigger Binding="{Binding ElementName=TheField, Path=IsKeyboardFocusWithin}" Value="True">
                                    <Setter Property="Visibility" Value="Hidden"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=TheField, Path=Text.IsEmpty}" Value="False">
                                    <Setter Property="Visibility" Value="Hidden"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBox.Style>
                </TextBox>
            </Grid>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...