我怎么能把一些文本放入一个文本框,这将被自动删除时,用户键入的东西在它?


当前回答

该技术使用Background属性来显示/隐藏占位符文本框。 占位符显示事件时,文本框有焦点

工作原理:

当为空时,文本框背景设置为透明以显示占位符文本。 当不空背景设置为白色,以掩盖占位符文本。

这里有一个基本的例子。出于我自己的目的,我把它变成了一个UserControl。

<Grid>
    <Grid.Resources>
        <ux:NotEmptyConverter x:Key="NotEmptyConverter" />

        <Style TargetType="{x:Type Control}" x:Key="DefaultStyle">
            <Setter Property="FontSize" Value="20" />
            <Setter Property="Margin" Value="10"/>
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
        </Style>

        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultStyle}"></Style>

    </Grid.Resources>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0" Text="Placeholder Text Is Here" Foreground="DarkGray" />
    <TextBox Grid.Row="0" Name="TextBoxEdit" 
            Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
        <TextBox.Style>
            <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultStyle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=FirstName.Length, FallbackValue=0, TargetNullValue=0}" Value="0">
                        <Setter Property="Background" Value="Transparent"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=FirstName, FallbackValue=0, TargetNullValue=0, Converter={StaticResource NotEmptyConverter}}" Value="false">
                        <Setter Property="Background" Value="White"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>
</Grid>

下面是ValueConverter,用于检测DataTrigger中的非空字符串。

public class NotEmptyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var s = value as string;
        return string.IsNullOrEmpty(s);
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

其他回答

<TextBox Controls:TextBoxHelper.Watermark="Watermark"/>

添加mahapps。地铁到你的项目。 将带有上述代码的文本框添加到窗口中。

CodeProject上有一篇关于如何在“3行XAML”中做到这一点的文章。

<Grid Background="{StaticResource brushWatermarkBackground}">
  <TextBlock Margin="5,2" Text="Type something..."
             Foreground="{StaticResource brushForeground}"
             Visibility="{Binding ElementName=txtUserEntry, Path=Text.IsEmpty,
                          Converter={StaticResource BooleanToVisibilityConverter}}" />
  <TextBox Name="txtUserEntry" Background="Transparent"
           BorderBrush="{StaticResource brushBorder}" />
</Grid>

好吧,它可能不是3行XAML格式的,但它非常简单。

需要注意的一点是:文本上的IsEmpty属性不是string的属性,而是ICollectionView的属性,并且可以显式地设置为Path=Text.(componentModel:ICollectionView.IsEmpty) (with xmlns:componentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase")。这里有详细的解释。

最简单的方法水印的文本框

 <Window.Resources>
    <Style x:Key="MyWaterMarkStyle" TargetType="{x:Type TextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid>
                        <Border Background="White" BorderBrush="#FF7D8683" BorderThickness="1"/>
                        <ScrollViewer x:Name="PART_ContentHost" Margin="5,0,0,0" VerticalAlignment="Center" />
                        <Label Margin="5,0,0,0" x:Name="WaterMarkLabel" Content="{TemplateBinding Tag}" VerticalAlignment="Center"
                           Visibility="Collapsed" Foreground="Gray" FontFamily="Arial"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Text" Value=""/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Visibility" TargetName="WaterMarkLabel" Value="Visible"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Foreground" Value="DimGray"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

并添加文本框StaticResource样式

  <TextBox
                Style="{StaticResource MyWaterMarkStyle}"
                Tag="Search Category"
                Grid.Row="0"
                Text="{Binding CategorySearch,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                TextSearch.Text="Search Category"
                >

好吧,这是我的:不一定是最好的,但因为它很简单,很容易编辑到你的口味。

<UserControl x:Class="WPFControls.ShadowedTextBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPFControls"
    Name="Root">
<UserControl.Resources>
    <local:ShadowConverter x:Key="ShadowConvert"/>
</UserControl.Resources>
<Grid>
    <TextBox Name="textBox" 
             Foreground="{Binding ElementName=Root, Path=Foreground}"
             Text="{Binding ElementName=Root, Path=Text, UpdateSourceTrigger=PropertyChanged}"
             TextChanged="textBox_TextChanged"
             TextWrapping="Wrap"
             VerticalContentAlignment="Center"/>
    <TextBlock Name="WaterMarkLabel"
           IsHitTestVisible="False"
           Foreground="{Binding ElementName=Root,Path=Foreground}"
           FontWeight="Thin"
           Opacity=".345"
           FontStyle="Italic"
           Text="{Binding ElementName=Root, Path=Watermark}"
           VerticalAlignment="Center"
           TextWrapping="Wrap"
           TextAlignment="Center">
        <TextBlock.Visibility>
            <MultiBinding Converter="{StaticResource ShadowConvert}">
                <Binding ElementName="textBox" Path="Text"/>
            </MultiBinding>
        </TextBlock.Visibility> 
    </TextBlock>
</Grid>

这个转换器,就像它现在写的那样,它不一定是一个MultiConverter,但这样它可以很容易地扩展

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WPFControls
{
    class ShadowConverter:IMultiValueConverter
    {
        #region Implementation of IMultiValueConverter

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var text = (string) values[0];
            return text == string.Empty
                       ? Visibility.Visible
                       : Visibility.Collapsed;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            return new object[0];
        }

        #endregion
    }
}

最后是背后的代码:

using System.Windows;
using System.Windows.Controls;

namespace WPFControls
{
    /// <summary>
    /// Interaction logic for ShadowedTextBox.xaml
    /// </summary>
    public partial class ShadowedTextBox : UserControl
    {
        public event TextChangedEventHandler TextChanged;

        public ShadowedTextBox()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.Register("Watermark",
                                        typeof (string),
                                        typeof (ShadowedTextBox),
                                        new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text",
                                        typeof (string),
                                        typeof (ShadowedTextBox),
                                        new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty TextChangedProperty =
            DependencyProperty.Register("TextChanged",
                                        typeof (TextChangedEventHandler),
                                        typeof (ShadowedTextBox),
                                        new UIPropertyMetadata(null));

        public string Watermark
        {
            get { return (string)GetValue(WatermarkProperty); }
            set
            {
                SetValue(WatermarkProperty, value);
            }
        }

        public string Text
        {
            get { return (string) GetValue(TextProperty); }
            set{SetValue(TextProperty,value);}
        }

        private void textBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (TextChanged != null) TextChanged(this, e);
        }

        public void Clear()
        {
            textBox.Clear();
        }

    }
}

设置文本框的占位符文本在一个柔和的颜色…

public MainWindow ( )
{
    InitializeComponent ( );
    txtInput.Text = "Type something here...";
    txtInput.Foreground = Brushes.DimGray;
}

当文本框获得焦点时,清除它并更改文本颜色

private void txtInput_GotFocus ( object sender, EventArgs e )
{
    MessageBox.Show ( "got focus" );
    txtInput.Text = "";
    txtInput.Foreground = Brushes.Red;
}