WPF中给文本框和密码框添加水印

编辑器加载中...在WPF中,给文本框添加一个水印可以有好几种方法,但是密码框有点不好做了,大部分都是重写控件继承于文本框以及集合依赖属性实现的,

在网上找了很久都没有类似的,在国外网站上看到的,顺便改了一下,当输入内容时水印消失(得到焦点时水印消失,暂时没做),如下如所示:

xaml的页面代码如下(里面的图片可以自己换):

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfTest="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

        <Style x:Key="MyTextBox" TargetType="{x:Type TextBox}">
            <Setter Property="WpfTest:TextBoxMonitor.IsMonitoring"  Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border Name="Bd"  Background="{TemplateBinding Background}"  BorderThickness="{TemplateBinding BorderThickness}"
                          BorderBrush="{TemplateBinding BorderBrush}"  SnapsToDevicePixels="true">
                            <Grid>
                                <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                <StackPanel Orientation="Horizontal" Visibility="Collapsed" Name="myStackPanel">
                                    <Image Source="1.png"/>
                                    <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="Red" Text="请输入用户名 "/>
                                </StackPanel>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Visibility" TargetName="myStackPanel" Value="Collapsed"/>
                            </Trigger>
                            <Trigger Property="WpfTest:TextBoxMonitor.TextBoxLength" Value="0">
                                <Setter Property="Visibility" TargetName="myStackPanel" Value="Visible"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="MyPasswordBox" TargetType="{x:Type PasswordBox}">
            <Setter Property="WpfTest:PasswordBoxMonitor.IsMonitoring"  Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type PasswordBox}">
                        <Border Name="Bd"  Background="{TemplateBinding Background}"  BorderThickness="{TemplateBinding BorderThickness}"
                          BorderBrush="{TemplateBinding BorderBrush}"  SnapsToDevicePixels="true">
                            <Grid>
                                <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                <StackPanel Orientation="Horizontal" Visibility="Collapsed" Name="myStackPanel">
                                    <Image Source="1.png"/>
                                    <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="Red" Text="请输入用户密码 "/>
                                </StackPanel>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Visibility" TargetName="myStackPanel" Value="Collapsed"/>
                            </Trigger>
                            <Trigger Property="WpfTest:PasswordBoxMonitor.PasswordLength" Value="0">
                                <Setter Property="Visibility" TargetName="myStackPanel" Value="Visible"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        
        <PasswordBox VerticalAlignment="Top"  Height="45" Style="{StaticResource MyPasswordBox}" Margin="143,71,114,0" />

        <TextBox Height="43" HorizontalAlignment="Left" Margin="143,12,0,0" Name="textBox1" Style="{StaticResource MyTextBox}" VerticalAlignment="Top" Width="246" />
        
        <!--这个是用样式实现的文本框加水印,上面的两个是通过添加依赖属性实现的-->
        <TextBox Height="43" x:Name="txt" Margin="143,0,114,125" VerticalAlignment="Bottom">
            <TextBox.Style>
                <Style TargetType="{x:Type TextBox}">
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="TextBox.IsFocused" Value="False"/>
                                <Condition Property="TextBox.Text" Value=""/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="TextBox.Background">
                                    <Setter.Value>
                                        <VisualBrush Opacity="0.4" AlignmentX="Left" Stretch="None">
                                            <VisualBrush.Visual>
                                                <StackPanel Orientation="Horizontal">
                                                    <Image Source="1.png"/>
                                                    <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Text="请输入用户名 "/>
                                                </StackPanel>
                                            </VisualBrush.Visual>
                                        </VisualBrush>
                                    </Setter.Value>
                                </Setter>
                            </MultiTrigger.Setters>
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
    </Grid>
</Window>

CS代码如下(可以自己去写简单的控件):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }

    }

    //密码框的水印附加属性
    public class PasswordBoxMonitor : DependencyObject
    {
        public static bool GetIsMonitoring(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsMonitoringProperty);
        }

        public static void SetIsMonitoring(DependencyObject obj, bool value)
        {
            obj.SetValue(IsMonitoringProperty, value);
        }

        public static readonly DependencyProperty IsMonitoringProperty =
            DependencyProperty.RegisterAttached("IsMonitoring", typeof(bool), typeof(PasswordBoxMonitor), new UIPropertyMetadata(false, OnIsMonitoringChanged));



        public static int GetPasswordLength(DependencyObject obj)
        {
            return (int)obj.GetValue(PasswordLengthProperty);
        }

        public static void SetPasswordLength(DependencyObject obj, int value)
        {
            obj.SetValue(PasswordLengthProperty, value);
        }

        public static readonly DependencyProperty PasswordLengthProperty =
            DependencyProperty.RegisterAttached("PasswordLength", typeof(int), typeof(PasswordBoxMonitor), new UIPropertyMetadata(0));

        private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var pb = d as PasswordBox;
            if (pb == null)
            {
                return;
            }
            if ((bool)e.NewValue)
            {
                pb.PasswordChanged += PasswordChanged;
            }
            else
            {
                pb.PasswordChanged -= PasswordChanged;
            }
        }

        static void PasswordChanged(object sender, RoutedEventArgs e)
        {
            var pb = sender as PasswordBox;
            if (pb == null)
            {
                return;
            }
            SetPasswordLength(pb, pb.Password.Length);
        }
    }

    //文本框的水印附加属性
    public class TextBoxMonitor : DependencyObject
    {
        public static bool GetIsMonitoring(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsMonitoringProperty);
        }

        public static void SetIsMonitoring(DependencyObject obj, bool value)
        {
            obj.SetValue(IsMonitoringProperty, value);
        }

        public static readonly DependencyProperty IsMonitoringProperty =
            DependencyProperty.RegisterAttached("IsMonitoring", typeof(bool), typeof(TextBoxMonitor), new UIPropertyMetadata(false, OnIsMonitoringChanged));



        public static int GetTextBoxLength(DependencyObject obj)
        {
            return (int)obj.GetValue(TextBoxLengthProperty);
        }

        public static void SetTextBoxLength(DependencyObject obj, int value)
        {
            obj.SetValue(TextBoxLengthProperty, value);
        }

        public static readonly DependencyProperty TextBoxLengthProperty =
            DependencyProperty.RegisterAttached("TextBoxLength", typeof(int), typeof(TextBoxMonitor), new UIPropertyMetadata(0));

        private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var tx = d as TextBox;
            if (tx == null)
            {
                return;
            }
            if ((bool)e.NewValue)
            {
                tx.TextChanged += new TextChangedEventHandler(tx_TextChanged);
            }
            else
            {
                tx.TextChanged -= new TextChangedEventHandler(tx_TextChanged);
            }
        }

        static void tx_TextChanged(object sender, TextChangedEventArgs e)
        {
            var tx = sender as TextBox;
            if (tx == null)
            {
                return;
            }
            SetTextBoxLength(tx, tx.Text.Length);
        }

        
    }

}

 

 

posted @ 2012-08-16 16:25  sky300  阅读(1707)  评论(0编辑  收藏  举报