主要功能皆为参考他人代码,在这里做封装汇总,没想到html上面一个placehode就能实现的功能,在wpf上要几百行代码才能实现……
1.准备两个样式文件
PasswordBoxStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Core="clr-namespace:WpfApp1.Core">
<Style TargetType="PasswordBox">
<Setter Property="Foreground" Value="#000000"/>
<Setter Property="FontSize" Value="16"/>
<!--光标的颜色-->
<Setter Property="CaretBrush" Value="Green"/>
<Setter Property="Core:PasswordBoxWaterMark.IsMonitoring" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<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="WaterMark" Focusable="False" Visibility="Collapsed" Padding="7" Text="{TemplateBinding Tag}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Opacity="0.5"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Core:PasswordBoxWaterMark.PasswordLength" Value="0">
<Setter TargetName="WaterMark" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TextBoxStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Convert="clr-namespace:WpfApp1.Converters"
xmlns:Core="clr-namespace:WpfApp1.Core"
xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore">
<Style x:Key="TxbBase" TargetType="TextBox">
<Setter Property="Foreground" Value="#000000"/>
<Setter Property="FontSize" Value="14"/>
<!--光标的颜色-->
<Setter Property="CaretBrush" Value="Green"/>
<!--屏蔽系统右键菜单-->
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu Visibility="Collapsed"/>
</Setter.Value>
</Setter>
<!--用来禁用掉中文输入法-->
<!--<Setter Property="input:InputMethod.IsInputMethodEnabled" Value="False"/>-->
</Style>
<Convert:TextToVisibility x:Key="TextToVisibility"/>
<!--触发器的形式进行水印效果-->
<Style x:Key="TxbTrigger" TargetType="TextBox" BasedOn="{StaticResource TxbBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="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 Padding="7" x:Name="WaterMark" Focusable="False" Visibility="Collapsed" Text="{TemplateBinding Tag}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Opacity="0.5"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<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>
<Trigger Property="Text" Value="">
<Setter Property="Visibility" TargetName="WaterMark" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--绑定和转换器的形式进行水印效果-->
<Style x:Key="TxbBing" TargetType="TextBox" BasedOn="{StaticResource TxbBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="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="WaterMark" Focusable="False" Visibility="{TemplateBinding Text,Converter={StaticResource TextToVisibility}}" Padding="7" Text="{TemplateBinding Tag}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Opacity="0.5"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<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>
</Setter.Value>
</Setter>
</Style>
注意修改xaml文件的头中的命名空间为自己项目的命名控件
做两个工具类,用于转化水印与正文
TextToVisibility.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
namespace WpfApp1.Converters
{
/// <summary>
/// 文本内容转换水印的可见性
/// </summary>
public class TextToVisibility : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//转换后的结果
Visibility visible = Visibility.Visible;
if (value != null)
{
string text = value.ToString();
if (!string.IsNullOrEmpty(text.Trim()))
{
int length = text.Length;
if (length > 0)
{
visible = Visibility.Collapsed;
}
}
}
return visible;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return string.Empty;
}
}
}
PasswordBoxWaterMark.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1.Core
{
/// <summary>
/// PasswordBox添加水印辅助类
/// </summary>
public class PasswordBoxWaterMark : 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(PasswordBoxWaterMark), 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(PasswordBoxWaterMark), 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;
}
}
private static void PasswordChanged(object sender, RoutedEventArgs e)
{
var pb = sender as PasswordBox;
if (pb == null)
{
return;
}
SetPasswordLength(pb, pb.Password.Length);
}
}
}
同样注意修改命名空间
3.在App.xaml中引用样式文件
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Css/TextBoxStyle.xaml"/>
<ResourceDictionary Source="/Css/PasswordBoxStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
4.在控件中引入样式
TextBox文本框
<TextBox Style="{StaticResource TxbTrigger}" Tag="请输入用户名" />
PasswordBox密码框
<PasswordBox Tag="请输入密码" />
实现功能
demo下载地址(引用)
http://files.cnblogs.com/files/OhMonkey/Demo.zip