• WindowsPhone自定义控件详解(三) 实战:自定义带水印的PasswordBox控件,WatermarkedPasswordBox


    ++++++++++++++++++++++++++++++++++++++++++

    本文系本站原创,欢迎转载! 转载请注明出处:

    http://blog.csdn.net/mr_raptor/article/details/7251992

    ++++++++++++++++++++++++++++++++++++++++++

     

    声明:这个控件是在WatermarkedTextBox的基础上改的。

    原创地址:http://blog.csdn.net/mr_raptor/article/details/7251992

    原理分析:

    在PasswordBox后面加水印和在TextBox后面加水印差不多,有以下要求:

    1. PasswordBox里没内容时,显示水印
    2. PasswordBox里有内容时,不显示水印,而显示内容

    最简单的想法就是,在PasswordBox控件后面加上一个类似TextBlock的控件,然后重写焦点回调方法,当有焦点时,水印不显示,无焦点时,根据是否有内容而决定是否显示水印。

    思路如上,下面开始分析WatermarkedTextBox的代码,看看它的作者是不是和我们想法一样。

    一、 分析WatermarkedTextBox代码

     

    1. themes/generic.xaml

    自定义控件的样式文件必须要以generic.xaml命名,放到themes目录中。

    注:上面省略了一部分无关紧要代码。
    http://blog.csdn.net/mr_raptor/article/details/7251992

    上面的XAML文件,定义了WatermarkedTextBox的样式:

    • 文件开始,定义了一个ControlTemplate元素,由前两节知识可知,它是要对一个控件设置模板,从后面的TargetType="TextBox"可知,是针对TextBox类型控件,它里面自定义了一个ContentControl类名字为ContentElement。
    • 通过TargetType="local:WatermarkedTextBox" 可知,它是针对WatermarkedTextBox的控件样式。
    • 在EnabledBorder里定义了两个内容控件元素:watermarkContent和ContentElement,watermarkContent里,绑定了依赖属性Watermark(在WatermarkTextBox.cs里声明)。
    • 在下面的DisabledOrReadonlyBorder里面是一个TextBox 控件,它绑定了WatermarkedTextBox里的Text属性,同时这个TextBox 控件,的模板设置为:PhoneDisabledTextBoxTemplate,它这么做的目的是,可以设置WatermarkedTextBox的属性为Disabled,这时,水印就消失了,而显示原先的TextBox控件。

           2. WatermarkTextBox.cs

    原创地址:http://blog.csdn.net/mr_raptor/article/details/7251992
    由这个WatermarkedTextBox类可知:

    • 它继承了TextBox类
    • 增加了Watermark和WatermarkStyle两个依赖属性,用于用户设置它的水印内容和样式,在Watermark属性里添加了属性改变事件:OnWatermarkPropertyChanged
    • 重载了OnApplyTemplate方法来取得generic.xaml文件里声明的元素引用:watermarkContent,并且根据generic.xaml里的TextBox :DisabledOrReadonlyContent,取得它里面是否有内容,如果有内容,则WatermarkContent不可见,否则WatermarkContent可见。
    • 重载了OnGotFocus,OnLostFocus,当该自定义控件得到焦点时,设置WatermarkContent不可见,否则WatermarkContent可见。

    由上面的分析可知,当用户设置了自定义控件的Watermark属性时,回调注册的OnWatermarkPropertyChanged方法,在该方法里,判断是否WatermarkContent里有内容,如果有,WatermarkContent不可见,否则WatermarkContent可见。两样,重载了OnGotFocus,OnLostFocus,在得到和失去焦点时也要判断是否将WatermarkContent设置为可见与否。

    二、 自定义WatermarkedPasswordBox

      根据前面的分析,我们可以试着做以下修改:

    • 新建类WatermarkedPasswordBox
    • 将WatermarkTextBox.cs拷贝到类WatermarkedPasswordBox里,改下类名,让WatermarkedPasswordBox继承了Password类
    • 在themes/generic.xaml里,拷贝 <Style  TargetType="local:WatermarkedPasswordBox">里的全部代码,改为WatermarkedPasswordBox的代码,中间细节自己改就行了,我们不打算支持Disabled属性,所以DisabledOrReadonlyBorder去掉就行了,将EnabledBorder里的ContentElement去掉,换成PasswordBox,名字还是ContentElement

    编译时,错误出现了:WatermarkedPasswordBox里this.Text出错,这是因为Password没有Text属性,它有个Password属性,所以要做下面的修改:

    • 让WatermarkedPasswordBox类继承TextBox,但是添加一个属性:PasswordBox类型的PasswordContent
    • 在OnApplyTemplate方法里,获得自己加的PasswordBox控件的引用ContentElement,为PasswordBox控件添加PasswordChanged事件,当密码框里内容改变时,将TextBox的Text属性的值为PasswordBox.Password的值
    • 同样,在XAML样式文件里,在PasswordBox控件里加上 Password="{TemplateBinding Text}"

    修改后的代码如下:

    XAML:

    原创地址:http://blog.csdn.net/mr_raptor/article/details/7251992
    C#:


    编译通过,将生成的库引入到Demo程序里,然后将控件加上,成功,效果如下。

    左图,未输入内容,显示水印,右图,输入内容时显示效果。

    ++++++++++++++++++++++++++++++++++++++++++

    本文系本站原创,欢迎转载! 转载请注明出处:

    http://blog.csdn.net/mr_raptor/article/details/7251992

    ++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    w3c盒子模型与ie盒子模型
    前端入门
    连接数据库好用工具
    前端开发工具
    刚发现的取色工具
    使用val()另一个妙用------选中select/checkbox/radio的值
    z-index的妙用
    react生命周期函数
    react中虚拟dom的diff算法
    React中的虚拟DOM
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2458033.html
Copyright © 2020-2023  润新知