Win8应用开发之带水印文本框

主题:开发带有水印的文本框控件。水印格式可以自定义。

 

1. 最后结果

如图:

 

2. 主要思想

   1. 在原来的TextBox中,添加并注册一个依赖属性:Watermark,用于前台自定义水印。

 2. 在原来的TextBox样式,添加一个用于呈现水印的内容控件:ContentPresenter,并且将Content绑定Watermark。

   3. 给整体控件添加GetFocus,LostFocus事件。以便,在获得焦点时,消失水印。失去焦点时,显示水印。

 

3. 新建项目和空间

1.新建一个项目:WatermarkerTextBoxControl

2.右击项目,添加新建项,选择模板式控件,并命名为WatermarkerTextBox.cs

Win8应用开发之带水印文本框_第1张图片

 

 

3.将下面代码拷入该模板控件里面:

 1 public sealed class WatermarkTextBox : TextBox
 2     {
 3         public static DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(object), typeof(WatermarkTextBox), new PropertyMetadata(null));
 4         public object Watermark
 5         {
 6             get { return (object)GetValue(WatermarkProperty); }
 7             set { SetValue(WatermarkProperty, value); }
 8         }
 9         public static DependencyProperty WatermarkTemplateProperty = DependencyProperty.Register("WatermarkTemplate", typeof(DataTemplate), typeof(WatermarkTextBox), new PropertyMetadata(null));
10         public DataTemplate WatermarkTemplate
11         {
12             get { return (DataTemplate)GetValue(WatermarkTemplateProperty); }
13             set { SetValue(WatermarkTemplateProperty, value); }
14         }
15 
16         public WatermarkTextBox()
17         {
18             this.DefaultStyleKey = typeof(WatermarkTextBox);
19             this.DefaultStyleKey = typeof(WatermarkTextBox);
20             this.GotFocus += WatermarkTextBox_GotFocus;
21             this.LostFocus += WatermarkTextBox_LostFocus;
22         }
23         void WatermarkTextBox_GotFocus(object sender, RoutedEventArgs e)
24         {
25             GoToWatermarkVisualState();
26         }
27 
28         void WatermarkTextBox_LostFocus(object sender, RoutedEventArgs e)
29         {
30             GoToWatermarkVisualState(false);
31         }
32 
33         private void GoToWatermarkVisualState(bool hasFocus = true)
34         {
35             //如果文本框内容为空 或者 没有获得焦点时,显示水印
36             //否则,就隐藏水印
37             if (String.IsNullOrEmpty(Text) && !hasFocus)
38                 GoToVisualState("WatermarkVisible"); //TODO: create constants for our magic strings
39             else
40                 GoToVisualState("WatermarkCollapsed");
41         }
42 
43         private void GoToVisualState(string stateName, bool useTransitions = true)
44         {
45             //控制水印状态
46             VisualStateManager.GoToState(this, stateName, useTransitions);
47         }
48 
49         protected override void OnApplyTemplate()
50         {
51             base.OnApplyTemplate();
52 
53             //we need to set the initial state of the watermark
54             GoToWatermarkVisualState(false);
55         }
56 
57     }
View Code

  代码讲解:

1). 给该控件注册,两个依赖属性,并且添加相应的属性索引器。但是有用的只是:Watermark属性。

2). 在控件构造函数中,添加GetFocus和LostFocus事件,并在事件中添加水印显示与否代码。

3). 水印的控制VisualState会写在该控件的样式中

 

4. 重写WatermarkTextBox的样式

1. 打开Theme文件夹下的Generic.xaml文件:

Win8应用开发之带水印文本框_第2张图片

2. 将下面的样式代码替换原来的WatermarkTextBox样式:

  1 <Style TargetType="local:WatermarkTextBox">
  2         <Setter Property="MinWidth" Value="{StaticResource TextControlThemeMinWidth}"/>
  3         <Setter Property="MinHeight" Value="{StaticResource TextControlThemeMinHeight}"/>
  4         <Setter Property="Foreground" Value="{StaticResource TextBoxForegroundThemeBrush}"/>
  5         <Setter Property="Background" Value="{StaticResource TextBoxBackgroundThemeBrush}"/>
  6         <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorderThemeBrush}"/>
  7         <Setter Property="BorderThickness" Value="{StaticResource TextControlBorderThemeThickness}"/>
  8         <Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
  9         <Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
 10         <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
 11         <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
 12         <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
 13         <Setter Property="Padding" Value="{StaticResource TextControlThemePadding}"/>
 14         <Setter Property="Template">
 15             <Setter.Value>
 16                 <ControlTemplate TargetType="local:WatermarkTextBox">
 17                     <Grid>
 18                         <Grid.Resources>
 19                             <Style x:Name="DeleteButtonStyle" TargetType="Button">
 20                                 <Setter Property="Template">
 21                                     <Setter.Value>
 22                                         <ControlTemplate TargetType="Button">
 23                                             <Grid>
 24                                                 <VisualStateManager.VisualStateGroups>
 25                                                     <VisualStateGroup x:Name="CommonStates">
 26                                                         <VisualState x:Name="Normal"/>
 27                                                         <VisualState x:Name="PointerOver">
 28                                                             <Storyboard>
 29                                                                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
 30                                                                     <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPointerOverBackgroundThemeBrush}"/>
 31                                                                 </ObjectAnimationUsingKeyFrames>
 32                                                                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
 33                                                                     <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPointerOverBorderThemeBrush}"/>
 34                                                                 </ObjectAnimationUsingKeyFrames>
 35                                                                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement">
 36                                                                     <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPointerOverForegroundThemeBrush}"/>
 37                                                                 </ObjectAnimationUsingKeyFrames>
 38                                                             </Storyboard>
 39                                                         </VisualState>
 40                                                         <VisualState x:Name="Pressed">
 41                                                             <Storyboard>
 42                                                                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
 43                                                                     <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedBackgroundThemeBrush}"/>
 44                                                                 </ObjectAnimationUsingKeyFrames>
 45                                                                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
 46                                                                     <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedBorderThemeBrush}"/>
 47                                                                 </ObjectAnimationUsingKeyFrames>
 48                                                                 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement">
 49                                                                     <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxButtonPressedForegroundThemeBrush}"/>
 50                                                                 </ObjectAnimationUsingKeyFrames>
 51                                                             </Storyboard>
 52                                                         </VisualState>
 53                                                         <VisualState x:Name="Disabled">
 54                                                             <Storyboard>
 55                                                                 <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
 56                                                                 <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
 57                                                             </Storyboard>
 58                                                         </VisualState>
 59                                                     </VisualStateGroup>                        
 60                                                 </VisualStateManager.VisualStateGroups>
 61                                                 <Border x:Name="BorderElement" BorderBrush="{StaticResource TextBoxButtonBorderThemeBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
 62                                                 <Border x:Name="BackgroundElement" Background="{StaticResource TextBoxButtonBackgroundThemeBrush}" Margin="{TemplateBinding BorderThickness}">
 63                                                     <TextBlock x:Name="GlyphElement" Foreground="{StaticResource TextBoxButtonForegroundThemeBrush}" FontFamily="{StaticResource SymbolThemeFontFamily}" HorizontalAlignment="Center" Text="&#xE0A4;" VerticalAlignment="Center"/>
 64                                                 </Border>
 65                                             </Grid>
 66                                         </ControlTemplate>
 67                                     </Setter.Value>
 68                                 </Setter>
 69                             </Style>
 70                         </Grid.Resources>
 71                         <Grid.ColumnDefinitions>
 72                             <ColumnDefinition Width="*"/>
 73                             <ColumnDefinition Width="Auto"/>
 74                         </Grid.ColumnDefinitions>
 75                         <VisualStateManager.VisualStateGroups>
 76                             <VisualStateGroup x:Name="WatermarkStates">
 77                                 <VisualState x:Name="WatermarkVisible">
 78                                     <Storyboard>
 79                                         <ObjectAnimationUsingKeyFrames Duration="0"  Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PART_Watermark">
 80                                             <DiscreteObjectKeyFrame KeyTime="0">
 81                                                 <DiscreteObjectKeyFrame.Value>
 82                                                     <Visibility>Visible</Visibility>
 83                                                 </DiscreteObjectKeyFrame.Value>
 84                                             </DiscreteObjectKeyFrame>
 85                                         </ObjectAnimationUsingKeyFrames>
 86                                     </Storyboard>
 87                                 </VisualState>
 88                                 <VisualState x:Name="WatermarkCollapsed" />
 89                             </VisualStateGroup>
 90                             <VisualStateGroup x:Name="CommonStates">
 91                                 <VisualState x:Name="Disabled">
 92                                     <Storyboard>
 93                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
 94                                             <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledBackgroundThemeBrush}"/>
 95                                         </ObjectAnimationUsingKeyFrames>
 96                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
 97                                             <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledBorderThemeBrush}"/>
 98                                         </ObjectAnimationUsingKeyFrames>
 99                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
100                                             <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TextBoxDisabledForegroundThemeBrush}"/>
101                                         </ObjectAnimationUsingKeyFrames>
102                                     </Storyboard>
103                                 </VisualState>
104                                 <VisualState x:Name="Normal">
105                                     <Storyboard>
106                                         <DoubleAnimation Duration="0" To="{StaticResource TextControlBackgroundThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
107                                         <DoubleAnimation Duration="0" To="{StaticResource TextControlBorderThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
108                                     </Storyboard>
109                                 </VisualState>
110                                 <VisualState x:Name="PointerOver">
111                                     <Storyboard>
112                                         <DoubleAnimation Duration="0" To="{StaticResource TextControlPointerOverBackgroundThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
113                                         <DoubleAnimation Duration="0" To="{StaticResource TextControlPointerOverBorderThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
114                                     </Storyboard>
115                                 </VisualState>
116                                 <VisualState x:Name="Focused"/>
117                             </VisualStateGroup>
118                             <VisualStateGroup x:Name="ButtonStates">
119                                 <VisualState x:Name="ButtonVisible">
120                                     <Storyboard>
121                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DeleteButton">
122                                             <DiscreteObjectKeyFrame KeyTime="0">
123                                                 <DiscreteObjectKeyFrame.Value>
124                                                     <Visibility>Visible</Visibility>
125                                                 </DiscreteObjectKeyFrame.Value>
126                                             </DiscreteObjectKeyFrame>
127                                         </ObjectAnimationUsingKeyFrames>
128                                     </Storyboard>
129                                 </VisualState>
130                                 <VisualState x:Name="ButtonCollapsed"/>
131                             </VisualStateGroup>
132                         </VisualStateManager.VisualStateGroups>
133                         <Border x:Name="BackgroundElement" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}"/>
134                         <Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2"/>
135                         <ScrollViewer x:Name="ContentElement" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"/>
136                         <ContentPresenter x:Name="PART_Watermark" 
137                                           Content="{TemplateBinding Watermark}" ContentTemplate="{TemplateBinding Watermark}"
138                                           IsHitTestVisible="False" Margin="{TemplateBinding Padding}" Visibility="Collapsed"/>
139                         <Button x:Name="DeleteButton" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" Style="{StaticResource DeleteButtonStyle}" Visibility="Collapsed" VerticalAlignment="Stretch"/>
140                     </Grid>
141                 </ControlTemplate>
142             </Setter.Value>
143         </Setter>
144     </Style>
View Code

 

5. 在需要的地方引用该控件

 1 <StackPanel Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
 2         <local:WatermarkTextBox FontSize="12">
 3             <local:WatermarkTextBox.Watermark>
 4                 <StackPanel Orientation="Horizontal">
 5                      <Image Source="ms-appx:///Asstes/edit.jpg"/>
 6                     <TextBlock Text="Edit Text" Foreground="Red" FontSize="20" Margin="4,0,0,0" />
 7                 </StackPanel>
 8             </local:WatermarkTextBox.Watermark>
 9         </local:WatermarkTextBox>
10 </StackPanel>        
View Code

 

6.参考文章:

http://elegantcode.com/2012/03/06/create-your-first-winrt-watermarktextbox-control/

你可能感兴趣的:(win8)