本文系本站原创,欢迎转载! 转载请注明出处:
http://blog.csdn.net/mr_raptor/article/details/7251992
++++++++++++++++++++++++++++++++++++++++++
声明:这个控件是在WatermarkedTextBox的基础上改的。
原创地址:http://blog.csdn.net/mr_raptor/article/details/7251992
原理分析:
在PasswordBox后面加水印和在TextBox后面加水印差不多,有以下要求:
最简单的想法就是,在PasswordBox控件后面加上一个类似TextBlock的控件,然后重写焦点回调方法,当有焦点时,水印不显示,无焦点时,根据是否有内容而决定是否显示水印。
思路如上,下面开始分析WatermarkedTextBox的代码,看看它的作者是不是和我们想法一样。
一、 分析WatermarkedTextBox代码
自定义控件的样式文件必须要以generic.xaml命名,放到themes目录中。
<ControlTemplate x:Key="PhoneDisabledTextBoxTemplate" TargetType="TextBox"> <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/> </ControlTemplate> <Style TargetType="local:WatermarkedTextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:WatermarkedTextBox"> <Grid Background="Transparent"> <Border x:Name="EnabledBorder"> <Grid> <ContentControl x:Name="watermarkContent" Style="{TemplateBinding WatermarkStyle}" Content="{TemplateBinding Watermark}" Background="Transparent" Opacity="0.5"/> <ContentControl x:Name="ContentElement" BorderThickness="0" VerticalContentAlignment="Stretch"/> </Grid> </Border> <Border x:Name="DisabledOrReadonlyBorder" Background="Transparent" Visibility="Collapsed"> <TextBox x:Name="DisabledOrReadonlyContent" Background="Transparent" IsReadOnly="True" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>注:上面省略了一部分无关紧要代码。
http://blog.csdn.net/mr_raptor/article/details/7251992
上面的XAML文件,定义了WatermarkedTextBox的样式:
2. WatermarkTextBox.cs
namespace WatermarkedTextBoxControl { public class WatermarkedTextBox : TextBox { ContentControl WatermarkContent; public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(object), typeof(WatermarkedTextBox), new PropertyMetadata(OnWatermarkPropertyChanged)); public static readonly DependencyProperty WatermarkStyleProperty = DependencyProperty.Register("WatermarkStyle", typeof(Style), typeof(WatermarkedTextBox), null); public Style WatermarkStyle { get { return base.GetValue(WatermarkStyleProperty) as Style; } set { base.SetValue(WatermarkStyleProperty, value); } } public object Watermark { get { return base.GetValue(WatermarkProperty) as object; } set { base.SetValue(WatermarkProperty, value); } } public WatermarkedTextBox() { DefaultStyleKey = typeof(WatermarkedTextBox); } public override void OnApplyTemplate() { base.OnApplyTemplate(); this.WatermarkContent = this.GetTemplateChild("watermarkContent") as ContentControl; if(WatermarkContent != null) { DetermineWatermarkContentVisibility(); } } protected override void OnGotFocus(RoutedEventArgs e) { if (WatermarkContent != null && string.IsNullOrEmpty(this.Text)) { this.WatermarkContent.Visibility = Visibility.Collapsed; } base.OnGotFocus(e); } protected override void OnLostFocus(RoutedEventArgs e) { if (WatermarkContent != null && string.IsNullOrEmpty(this.Text)) { this.WatermarkContent.Visibility = Visibility.Visible; } base.OnLostFocus(e); } private static void OnWatermarkPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { WatermarkedTextBox watermarkTextBox = sender as WatermarkedTextBox; if(watermarkTextBox != null && watermarkTextBox.WatermarkContent !=null) { watermarkTextBox.DetermineWatermarkContentVisibility(); } } private void DetermineWatermarkContentVisibility() { if (string.IsNullOrEmpty(this.Text)) { this.WatermarkContent.Visibility = Visibility.Visible; } else { this.WatermarkContent.Visibility = Visibility.Collapsed; } } } } }原创地址:http://blog.csdn.net/mr_raptor/article/details/7251992
由这个WatermarkedTextBox类可知:
由上面的分析可知,当用户设置了自定义控件的Watermark属性时,回调注册的OnWatermarkPropertyChanged方法,在该方法里,判断是否WatermarkContent里有内容,如果有,WatermarkContent不可见,否则WatermarkContent可见。两样,重载了OnGotFocus,OnLostFocus,在得到和失去焦点时也要判断是否将WatermarkContent设置为可见与否。
二、 自定义WatermarkedPasswordBox
根据前面的分析,我们可以试着做以下修改:
编译时,错误出现了:WatermarkedPasswordBox里this.Text出错,这是因为Password没有Text属性,它有个Password属性,所以要做下面的修改:
修改后的代码如下:
XAML:
<Style TargetType="local:WatermarkedPasswordBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:WatermarkedPasswordBox"> <Grid Background="Transparent"> <Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"> <Grid> <ContentControl x:Name="watermarkContent" Style="{TemplateBinding WatermarkStyle}" Content="{TemplateBinding Watermark}" Background="Transparent" Opacity="0.5"/> <PasswordBox x:Name="ContentElement" Background="Transparent" Password="{TemplateBinding Text}" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="-12,-12,-12,-12" VerticalContentAlignment="Stretch"/> </Grid> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>原创地址:http://blog.csdn.net/mr_raptor/article/details/7251992
C#:
编译通过,将生成的库引入到Demo程序里,然后将控件加上,成功,效果如下。
左图,未输入内容,显示水印,右图,输入内容时显示效果。
++++++++++++++++++++++++++++++++++++++++++
本文系本站原创,欢迎转载! 转载请注明出处:
http://blog.csdn.net/mr_raptor/article/details/7251992
++++++++++++++++++++++++++++++++++++++++++