WPF-23:水印文本框

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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值