当前位置:软件学习 > Word >>

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

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

从http://www.windowsphonegeek.com/articles/WP7-WatermarkedTextBox-custom-control上下载WatermarkedTextBox控件


原理分析:

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

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

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

 

 

一、 分析WatermarkedTextBox代码

 

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

[html] <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> 
 <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的样式:

文件开始,定义了一个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

[csharp] namespace WatermarkedTextBoxControl 

    public class WatermarkedTextBox : TextBox 
    { 
        ContentControl WatermarkContent; 
        public static readonly DependencyProperty WatermarkProperty = 
      DependencyProperty.Register("Watermark", typeof(object), typeof(WatermarkedTextBox), new PropertyMetadata(OnWatermarkPropertyChanged)); 
  
        public

补充:移动开发 , Windows Phone ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,