WPF-23:水印文本框

来源:互联网 发布:apache windows 64位 编辑:程序博客网 时间:2024/06/05 13:56

WPF中水印输入框应该是有很多地方使用,它的实现也比较简单。可以有两种方法,一是对TextBox进行控制,用代码实现。二是针对TextBox写一个样式实现。

效果如图,


先看第一种:
继承一个用户控件,上面放一个textbox,
<UserControl x:Class="TestTextBoxWaterMark.SelfWateMarkTextbox"             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"              mc:Ignorable="d" >    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">        <TextBox  Name="textBox1" VerticalAlignment="Stretch"  HorizontalAlignment="Stretch"/>    </Grid></UserControl>
后台,
    /// <summary>    /// WateMarkTextbox.xaml 的交互逻辑    /// </summary>    public partial class SelfWateMarkTextbox : UserControl    {        private const string defaultText = "请输入内容";        public SelfWateMarkTextbox()        {            InitializeComponent();            this.Loaded += new RoutedEventHandler(WateMarkTextbox_Loaded);            this.GotFocus += new RoutedEventHandler(WateMarkTextbox_GotFocus);            this.LostFocus += new RoutedEventHandler(WateMarkTextbox_LostFocus);            this.textBox1.TextChanged += new TextChangedEventHandler(TextBox1_TextChanged);        }        void TextBox1_TextChanged(object sender, TextChangedEventArgs e)        {            if (!string.IsNullOrWhiteSpace(this.textBox1.Text) || this.textBox1.IsFocused)            {                this.textBox1.Text = this.textBox1.Text;            }            else            {                this.textBox1.Text = Watermark;            }        }        void WateMarkTextbox_LostFocus(object sender, RoutedEventArgs e)        {            if (string.IsNullOrEmpty(this.textBox1.Text))            {                this.textBox1.Text = string.Empty;            }        }        void WateMarkTextbox_GotFocus(object sender, RoutedEventArgs e)        {            if (this.textBox1.Text.Equals(Watermark))            {                this.textBox1.Text = string.Empty;            }        }        void WateMarkTextbox_Loaded(object sender, RoutedEventArgs e)        {            this.textBox1.Text = Watermark;        }        public string Watermark        {            get            {                string result = (string)GetValue(WatermarkProperty);                if (string.IsNullOrEmpty(result))                {                    result = defaultText;                }                return result;            }            set { SetValue(WatermarkProperty, value); }        }        public static readonly DependencyProperty WatermarkProperty =            DependencyProperty.Register("Watermark", typeof(string), typeof(SelfWateMarkTextbox), new UIPropertyMetadata(defaultText));    }
效果如上图,第一个所示。
第二种,当然为了方便起见,可以直接使用样式控制:
直接继承TextBox,
   public class WateMarkTextBox:TextBox    {        private TextBlock wateMarkTextBlock;        private TextBox wateMarkTextBox;          static WateMarkTextBox()        {            DefaultStyleKeyProperty.OverrideMetadata(typeof(WateMarkTextBox), new FrameworkPropertyMetadata(typeof(WateMarkTextBox)));        }          public WateMarkTextBox()        {            this.GotFocus += new RoutedEventHandler(WateMarkTextBox_GotFocus);            this.LostFocus += new RoutedEventHandler(WateMarkTextBox_LostFocus);            this.TextChanged += new TextChangedEventHandler(WateMarkTextBox_TextChanged);        }          void WateMarkTextBox_LostFocus(object sender, RoutedEventArgs e)          {              if (this.wateMarkTextBox!=null && !string.IsNullOrWhiteSpace(this.wateMarkTextBox.Text))              {                  this.wateMarkTextBlock.Visibility = Visibility.Hidden;              }              else              {                  this.wateMarkTextBlock.Visibility = Visibility.Visible;              }          }          void WateMarkTextBox_GotFocus(object sender, RoutedEventArgs e)          {              this.wateMarkTextBlock.Visibility = Visibility.Hidden;          }          void WateMarkTextBox_TextChanged(object sender, TextChangedEventArgs e)          {              if (this.wateMarkTextBox != null && !string.IsNullOrWhiteSpace(this.wateMarkTextBox.Text) || !this.IsFocused)              {                  this.wateMarkTextBlock.Visibility = Visibility.Hidden;              }              else              {                  this.wateMarkTextBlock.Visibility = Visibility.Visible;              }          }          public string WateMark        {            get { return (string)GetValue(WateMarkProperty); }            set { SetValue(WateMarkProperty, value); }        }        public static DependencyProperty WateMarkProperty =            DependencyProperty.Register("WateMark", typeof(string), typeof(WateMarkTextBox), new UIPropertyMetadata("水印"));        public override void OnApplyTemplate()        {            base.OnApplyTemplate();            this.wateMarkTextBlock = this.GetTemplateChild("ChildWateMark") as TextBlock;            this.wateMarkTextBox = this.GetTemplateChild("ChildTextBox") as TextBox;        }    }
样式,
   <ResourceDictionary    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:sys="clr-namespace:System;assembly=mscorlib"    xmlns:local="clr-namespace:TestTextBoxWaterMark">    <Style  TargetType="{x:Type local:WateMarkTextBox}">        <Setter Property="IsTabStop" Value="False"/>        <Setter Property="Background" Value="White"/>        <Setter Property="BorderBrush" Value="#AAB5C0"/>        <Setter Property="Padding" Value="2"/>        <Setter Property="BorderThickness" Value="1"/>        <Setter Property="Foreground" Value="Black"/>        <Setter Property="MinWidth" Value="45"/>        <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="{x:Type local:WateMarkTextBox}">                    <Grid Opacity="{TemplateBinding Opacity}" >                        <Border BorderBrush="{TemplateBinding BorderBrush}"  CornerRadius="5" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" >                            <Grid>                                <Grid.ColumnDefinitions>                                    <ColumnDefinition Width="32"/>                                    <ColumnDefinition Width="*"/>                                </Grid.ColumnDefinitions>                                                                <TextBox Grid.Column="1" x:Name="ChildTextBox" VerticalContentAlignment="Center"  IsTabStop="True" Margin="2"                                          Padding="{TemplateBinding Padding}" BorderThickness="0" Background="Transparent" Foreground="{TemplateBinding Foreground}"/>                                <TextBlock x:Name="ChildWateMark" VerticalAlignment="Center" Foreground="LightGray" Text="{TemplateBinding WateMark}" Grid.Column="1"/>                            </Grid>                        </Border>                    </Grid>                </ControlTemplate>            </Setter.Value>        </Setter>    </Style></ResourceDictionary>
效果如上图第二个所示。

 上面的样式还有更好的实现,参考了网上一个比较好的样式实现,如下

   public class PerfectWateMarkTextBox : TextBox    {        private Label wateMarkLable;        private ScrollViewer wateMarkScrollViewer;        static PerfectWateMarkTextBox()        {            DefaultStyleKeyProperty.OverrideMetadata(typeof(PerfectWateMarkTextBox), new FrameworkPropertyMetadata(typeof(PerfectWateMarkTextBox)));        }        public PerfectWateMarkTextBox()        {            this.Loaded += new RoutedEventHandler(PerfectWateMarkTextBox_Loaded);        }        void PerfectWateMarkTextBox_LostFocus(object sender, RoutedEventArgs e)        {                    }        void PerfectWateMarkTextBox_Loaded(object sender, RoutedEventArgs e)        {            this.wateMarkLable.Content = WateMark;        }        void PerfectWateMarkTextBox_GotFocus(object sender, RoutedEventArgs e)        {            this.wateMarkLable.Visibility = Visibility.Hidden;        }        public string WateMark        {            get { return (string)GetValue(WateMarkProperty); }            set { SetValue(WateMarkProperty, value); }        }        public static DependencyProperty WateMarkProperty =            DependencyProperty.Register("WateMark", typeof(string), typeof(PerfectWateMarkTextBox), new UIPropertyMetadata("水印"));        public override void OnApplyTemplate()        {            base.OnApplyTemplate();            this.wateMarkLable = this.GetTemplateChild("TextPrompt") as Label;            this.wateMarkScrollViewer = this.GetTemplateChild("PART_ContentHost") as ScrollViewer;        }    }

对应的样式,

   <Style TargetType="{x:Type local:PerfectWateMarkTextBox}">        <Style.Resources>            <SolidColorBrush x:Key="WatermaskTextBoxWatermaskForeground" Color="#FF707070" />        </Style.Resources>        <Setter Property="SnapsToDevicePixels" Value="True"/>        <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>        <Setter Property="MinWidth" Value="120"/>        <Setter Property="MinHeight" Value="20"/>        <Setter Property="AllowDrop" Value="True"/>        <Setter Property="Foreground" Value="#FF000000"/>        <Setter Property="Background" Value="#FFFFFFFF"/>        <Setter Property="BorderBrush" Value="#FF707070"/>        <Setter Property="HorizontalAlignment" Value="Stretch"/>        <Setter Property="VerticalAlignment" Value="Center"/>        <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="{x:Type local:PerfectWateMarkTextBox}">                    <Border x:Name="Border" CornerRadius="2" Padding="2" Background="{TemplateBinding Background}"                             BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" >                        <Grid>                            <Label x:Name="TextPrompt" Content="{TemplateBinding Tag}" Focusable="False"                                     Foreground="{DynamicResource WatermaskTextBoxWatermaskForeground}" Height="{TemplateBinding Height}"                                   Visibility="Collapsed" Padding="5,0,0,0" VerticalContentAlignment="Center" Margin="2,0,0,0"/>                            <ScrollViewer Margin="0" x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>                        </Grid>                    </Border>                    <ControlTemplate.Triggers>                        <Trigger Property="IsFocused" Value="True">                            <Setter Property="BorderBrush" TargetName="Border" Value="{DynamicResource TextBoxFocusBorderBrush}"/>                        </Trigger>                        <Trigger Property="IsEnabled" Value="False">                            <Setter TargetName="Border" Property="Background" Value="{DynamicResource TextBoxDisabledBackground}"/>                            <Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource TextBoxDisabledBorderBrush}"/>                            <Setter Property="Foreground" Value="{DynamicResource TextBoxDisabledForeground}"/>                        </Trigger>                        <MultiTrigger>                            <MultiTrigger.Conditions>                                <Condition Property="IsFocused" Value="False"/>                                <Condition Property="IsEnabled" Value="True"/>                                <Condition Property="Text" Value=""/>                            </MultiTrigger.Conditions>                            <Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"/>                        </MultiTrigger>                        <MultiTrigger>                            <MultiTrigger.Conditions>                                <Condition Property="IsMouseOver" Value="True"/>                                <Condition Property="IsFocused" Value="False"/>                            </MultiTrigger.Conditions>                            <Setter Property="BorderBrush" TargetName="Border"                                     Value="{DynamicResource TextBoxMouseOverBorderBrush}"/>                        </MultiTrigger>                    </ControlTemplate.Triggers>                </ControlTemplate>            </Setter.Value>        </Setter>    </Style>
如上图中,第三个的实现。

详细代码下载:http://download.csdn.net/detail/yysyangyangyangshan/5797465

包括样式实现2的代码下载:http://download.csdn.net/detail/yysyangyangyangshan/5800519

原创粉丝点击