自定义水印输入框和密码框
一、水印输入框
要自定义水印输入框,就要先对TextBox的Template有些了解,下面是TextBox的Template
1 <ControlTemplate x:Key="PhoneDisabledTextBoxTemplate" TargetType="TextBox"> 2 <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/> 3 </ControlTemplate> 4 <Style x:Key="TextBoxStyle1" TargetType="TextBox"> 5 <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/> 6 <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/> 7 <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/> 8 <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/> 9 <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/> 10 <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/> 11 <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/> 12 <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/> 13 <Setter Property="Padding" Value="2"/> 14 <Setter Property="Template"> 15 <Setter.Value> 16 <ControlTemplate TargetType="TextBox"> 17 <Grid Background="Transparent"> 18 <VisualStateManager.VisualStateGroups> 19 <VisualStateGroup x:Name="CommonStates"> 20 <VisualState x:Name="Normal"/> 21 <VisualState x:Name="MouseOver"/> 22 <VisualState x:Name="Disabled"> 23 <Storyboard> 24 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 25 <DiscreteObjectKeyFrame KeyTime="0"> 26 <DiscreteObjectKeyFrame.Value> 27 <Visibility>Collapsed</Visibility> 28 </DiscreteObjectKeyFrame.Value> 29 </DiscreteObjectKeyFrame> 30 </ObjectAnimationUsingKeyFrames> 31 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder"> 32 <DiscreteObjectKeyFrame KeyTime="0"> 33 <DiscreteObjectKeyFrame.Value> 34 <Visibility>Visible</Visibility> 35 </DiscreteObjectKeyFrame.Value> 36 </DiscreteObjectKeyFrame> 37 </ObjectAnimationUsingKeyFrames> 38 </Storyboard> 39 </VisualState> 40 <VisualState x:Name="ReadOnly"> 41 <Storyboard> 42 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 43 <DiscreteObjectKeyFrame KeyTime="0"> 44 <DiscreteObjectKeyFrame.Value> 45 <Visibility>Collapsed</Visibility> 46 </DiscreteObjectKeyFrame.Value> 47 </DiscreteObjectKeyFrame> 48 </ObjectAnimationUsingKeyFrames> 49 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder"> 50 <DiscreteObjectKeyFrame KeyTime="0"> 51 <DiscreteObjectKeyFrame.Value> 52 <Visibility>Visible</Visibility> 53 </DiscreteObjectKeyFrame.Value> 54 </DiscreteObjectKeyFrame> 55 </ObjectAnimationUsingKeyFrames> 56 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledOrReadonlyBorder"> 57 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/> 58 </ObjectAnimationUsingKeyFrames> 59 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="DisabledOrReadonlyBorder"> 60 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/> 61 </ObjectAnimationUsingKeyFrames> 62 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent"> 63 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/> 64 </ObjectAnimationUsingKeyFrames> 65 </Storyboard> 66 </VisualState> 67 </VisualStateGroup> 68 <VisualStateGroup x:Name="FocusStates"> 69 <VisualState x:Name="Focused"> 70 <Storyboard> 71 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="EnabledBorder"> 72 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/> 73 </ObjectAnimationUsingKeyFrames> 74 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder"> 75 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/> 76 </ObjectAnimationUsingKeyFrames> 77 </Storyboard> 78 </VisualState> 79 <VisualState x:Name="Unfocused"/> 80 </VisualStateGroup> 81 </VisualStateManager.VisualStateGroups> 82 <Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"> 83 <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/> 84 </Border> 85 <Border x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"> 86 <TextBox x:Name="DisabledOrReadonlyContent" Background="Transparent" Foreground="{StaticResource PhoneDisabledBrush}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}" SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}" TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/> 87 </Border> 88 </Grid> 89 </ControlTemplate> 90 </Setter.Value> 91 </Setter> 92 </Style>
从上面的Template中分析发现,我们可以修改Name="EnabledBorder"的Border里的布局来实现我们的水印效果。
具体思路是,在<ContentControl x:Name="ContentElement" ......>的后面添加一个一样的ContentControl控件,来显示我们的水印内容,并根据TextBox的Text属性和聚焦状态动态的隐藏和显示我们添加的ContentControl。
实现步骤:
(一)、我们先创建一个引用库,创建一个文件夹名字为“Themes”,并在Themes文件夹下创建一个名字为“Generic.xaml”的文件并将文件 Generic.xaml的Build Action 设置为Resource。(注意:名字不可改) Generic.xaml代码如下:
1 <ResourceDictionary 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:WaterTextBox" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 7 mc:Ignorable="d"> 8 9 <ControlTemplate x:Key="PhoneDisabledTextBoxTemplate" TargetType="TextBox"> 10 <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/> 11 </ControlTemplate> 12 <Style TargetType="local:WaterTextBox"> 13 <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/> 14 <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/> 15 <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/> 16 <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/> 17 <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/> 18 <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/> 19 <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/> 20 <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/> 21 <Setter Property="Padding" Value="2"/> 22 <Setter Property="Template"> 23 <Setter.Value> 24 <ControlTemplate TargetType="local:WaterTextBox"> 25 <Grid Background="Transparent"> 26 <VisualStateManager.VisualStateGroups> 27 <VisualStateGroup x:Name="CommonStates"> 28 <VisualState x:Name="Normal"/> 29 <VisualState x:Name="MouseOver"/> 30 <VisualState x:Name="Disabled"> 31 <Storyboard> 32 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 33 <DiscreteObjectKeyFrame KeyTime="0"> 34 <DiscreteObjectKeyFrame.Value> 35 <Visibility>Collapsed</Visibility> 36 </DiscreteObjectKeyFrame.Value> 37 </DiscreteObjectKeyFrame> 38 </ObjectAnimationUsingKeyFrames> 39 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder"> 40 <DiscreteObjectKeyFrame KeyTime="0"> 41 <DiscreteObjectKeyFrame.Value> 42 <Visibility>Visible</Visibility> 43 </DiscreteObjectKeyFrame.Value> 44 </DiscreteObjectKeyFrame> 45 </ObjectAnimationUsingKeyFrames> 46 </Storyboard> 47 </VisualState> 48 <VisualState x:Name="ReadOnly"> 49 <Storyboard> 50 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 51 <DiscreteObjectKeyFrame KeyTime="0"> 52 <DiscreteObjectKeyFrame.Value> 53 <Visibility>Collapsed</Visibility> 54 </DiscreteObjectKeyFrame.Value> 55 </DiscreteObjectKeyFrame> 56 </ObjectAnimationUsingKeyFrames> 57 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder"> 58 <DiscreteObjectKeyFrame KeyTime="0"> 59 <DiscreteObjectKeyFrame.Value> 60 <Visibility>Visible</Visibility> 61 </DiscreteObjectKeyFrame.Value> 62 </DiscreteObjectKeyFrame> 63 </ObjectAnimationUsingKeyFrames> 64 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledOrReadonlyBorder"> 65 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/> 66 </ObjectAnimationUsingKeyFrames> 67 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="DisabledOrReadonlyBorder"> 68 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/> 69 </ObjectAnimationUsingKeyFrames> 70 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent"> 71 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/> 72 </ObjectAnimationUsingKeyFrames> 73 </Storyboard> 74 </VisualState> 75 </VisualStateGroup> 76 <VisualStateGroup x:Name="FocusStates"> 77 <VisualState x:Name="Focused"> 78 <Storyboard> 79 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="EnabledBorder"> 80 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/> 81 </ObjectAnimationUsingKeyFrames> 82 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder"> 83 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/> 84 </ObjectAnimationUsingKeyFrames> 85 </Storyboard> 86 </VisualState> 87 <VisualState x:Name="Unfocused"/> 88 </VisualStateGroup> 89 </VisualStateManager.VisualStateGroups> 90 <Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"> 91 <Grid> 92 <ContentControl x:Name="WaterCoElement" Content="{TemplateBinding WaterContent}" FontStyle="Italic" Foreground="{TemplateBinding WaterForeground}" Margin="{StaticResource PhoneTextBoxInnerMargin}" d:LayoutOverrides="Height" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/> 93 <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/> 94 </Grid> 95 </Border> 96 <Border x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"> 97 <TextBox x:Name="DisabledOrReadonlyContent" Background="Transparent" Foreground="{StaticResource PhoneDisabledBrush}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}" SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}" TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/> 98 </Border> 99 </Grid> 100 </ControlTemplate> 101 </Setter.Value> 102 </Setter> 103 </Style> 104 105 </ResourceDictionary>
(二)、创建我们的水印输入框控件类,使其继承TextBox。具体代码如下
1 using System; 2 using System.Net; 3 using System.Windows; 4 using System.Windows.Controls; 5 using System.Windows.Documents; 6 using System.Windows.Ink; 7 using System.Windows.Input; 8 using System.Windows.Media; 9 using System.Windows.Media.Animation; 10 using System.Windows.Shapes; 11 12 namespace WaterTextBox 13 { 14 public class WaterTextBox : TextBox 15 { 16 public static DependencyProperty WaterContentProprty = DependencyProperty.Register("WaterContent", typeof(object), typeof(WaterTextBox), new PropertyMetadata("水印输入框")); 17 18 public object WaterContent 19 { 20 get 21 { 22 return GetValue(WaterContentProprty); 23 } 24 25 set 26 { 27 SetValue(WaterContentProprty, value); 28 } 29 } 30 31 public static DependencyProperty WaterForegroundProprty = DependencyProperty.Register("WaterForeground", typeof(Brush), typeof(WaterTextBox), new PropertyMetadata(new SolidColorBrush(Colors.Gray))); 32 33 public Brush WaterForeground 34 { 35 get 36 { 37 return (Brush)GetValue(WaterForegroundProprty); 38 } 39 40 set 41 { 42 SetValue(WaterForegroundProprty, value); 43 } 44 } 45 46 public WaterTextBox() 47 { 48 DefaultStyleKey = typeof(WaterTextBox); 49 } 50 51 ContentControl WaterContentElement = null; 52 53 public override void OnApplyTemplate() 54 { 55 base.OnApplyTemplate(); 56 WaterContentElement = this.GetTemplateChild("WaterCoElement") as ContentControl; 57 if (WaterContentElement != null) 58 { 59 if (string.IsNullOrEmpty(Text)) 60 WaterContentElement.Visibility = System.Windows.Visibility.Visible; 61 else 62 WaterContentElement.Visibility = System.Windows.Visibility.Collapsed; 63 } 64 } 65 66 protected override void OnGotFocus(RoutedEventArgs e) 67 { 68 if (WaterContentElement != null && string.IsNullOrEmpty(Text)) 69 WaterContentElement.Visibility = Visibility.Collapsed; 70 base.OnGotFocus(e); 71 } 72 73 protected override void OnLostFocus(RoutedEventArgs e) 74 { 75 if (WaterContentElement != null && string.IsNullOrEmpty(Text)) 76 WaterContentElement.Visibility = Visibility.Visible; 77 base.OnLostFocus(e); 78 } 79 } 80 }
此处重载了TextBox的三个函数,分别是OnGotFocus、OnLostFocus和OnApplyTemplate,重载OnApplyTemplate在这里我们可以得到我们下名为WaterCoElement的ContentControl控件,来动态的控制显示隐藏。到这里我们的水印输入框就做好了。(注意:因为我们是使用ContentControl来显示水印的内容,而ContentControl的Content是Object,所以呢,我们可以在里面放任何复杂的控件)下面看下效果:
二、水印密码框
思路:既然水印输入框做好了,密码框和输入框差不多,我们是不是可以一样字画葫芦那?这个想法自然是最容易想到的,但可惜PasswordBox是一个封闭类,不可以继承,⊙﹏⊙b汗。那怎么办?既然TextBox和PasswordBox很相近,我们是不是可以从TextBox下手那。上面水印输入框是修改了Border.Name="EnabledBorder",在Border下面有一个ContentControl,那么我们把ContentControl换成PasswordBox是否可行那?让我们try一下吧。(PS:此处只是我做的时候一个想法,不过得到证实没有问题)
步骤同上面水印输入框一样,直接上代码:
1 <Style TargetType="local:WaterPasswordBox"> 2 <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/> 3 <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/> 4 <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/> 5 <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/> 6 <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/> 7 <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/> 8 <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/> 9 <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/> 10 <Setter Property="Padding" Value="2"/> 11 <Setter Property="Template"> 12 <Setter.Value> 13 <ControlTemplate TargetType="local:WaterPasswordBox"> 14 <Grid Background="Transparent"> 15 <VisualStateManager.VisualStateGroups> 16 <VisualStateGroup x:Name="CommonStates"> 17 <VisualState x:Name="Normal"/> 18 <VisualState x:Name="MouseOver"/> 19 <VisualState x:Name="Disabled"> 20 <Storyboard> 21 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 22 <DiscreteObjectKeyFrame KeyTime="0"> 23 <DiscreteObjectKeyFrame.Value> 24 <Visibility>Collapsed</Visibility> 25 </DiscreteObjectKeyFrame.Value> 26 </DiscreteObjectKeyFrame> 27 </ObjectAnimationUsingKeyFrames> 28 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder"> 29 <DiscreteObjectKeyFrame KeyTime="0"> 30 <DiscreteObjectKeyFrame.Value> 31 <Visibility>Visible</Visibility> 32 </DiscreteObjectKeyFrame.Value> 33 </DiscreteObjectKeyFrame> 34 </ObjectAnimationUsingKeyFrames> 35 </Storyboard> 36 </VisualState> 37 <VisualState x:Name="ReadOnly"> 38 <Storyboard> 39 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 40 <DiscreteObjectKeyFrame KeyTime="0"> 41 <DiscreteObjectKeyFrame.Value> 42 <Visibility>Collapsed</Visibility> 43 </DiscreteObjectKeyFrame.Value> 44 </DiscreteObjectKeyFrame> 45 </ObjectAnimationUsingKeyFrames> 46 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder"> 47 <DiscreteObjectKeyFrame KeyTime="0"> 48 <DiscreteObjectKeyFrame.Value> 49 <Visibility>Visible</Visibility> 50 </DiscreteObjectKeyFrame.Value> 51 </DiscreteObjectKeyFrame> 52 </ObjectAnimationUsingKeyFrames> 53 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledOrReadonlyBorder"> 54 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/> 55 </ObjectAnimationUsingKeyFrames> 56 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="DisabledOrReadonlyBorder"> 57 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/> 58 </ObjectAnimationUsingKeyFrames> 59 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent"> 60 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/> 61 </ObjectAnimationUsingKeyFrames> 62 </Storyboard> 63 </VisualState> 64 </VisualStateGroup> 65 <VisualStateGroup x:Name="FocusStates"> 66 <VisualState x:Name="Focused"> 67 <Storyboard> 68 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="EnabledBorder"> 69 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/> 70 </ObjectAnimationUsingKeyFrames> 71 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder"> 72 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/> 73 </ObjectAnimationUsingKeyFrames> 74 </Storyboard> 75 </VisualState> 76 <VisualState x:Name="Unfocused"/> 77 </VisualStateGroup> 78 </VisualStateManager.VisualStateGroups> 79 <Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"> 80 <Grid> 81 <ContentControl x:Name="WaterCoElement" Content="{TemplateBinding WaterContent}" FontStyle="Italic" Foreground="{TemplateBinding WaterForeground}" Margin="{StaticResource PhoneTextBoxInnerMargin}" d:LayoutOverrides="Height" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/> 82 <PasswordBox x:Name="ContentElement" Password="{TemplateBinding Text}" Background="{TemplateBinding Background}" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="-12" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/> 83 </Grid> 84 </Border> 85 <Border x:Name="DisabledOrReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"> 86 <TextBox x:Name="DisabledOrReadonlyContent" Background="Transparent" Foreground="{StaticResource PhoneDisabledBrush}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}" SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}" TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/> 87 </Border> 88 </Grid> 89 </ControlTemplate> 90 </Setter.Value> 91 </Setter> 92 </Style>
.Cs
1 using System; 2 using System.Net; 3 using System.Windows; 4 using System.Windows.Controls; 5 using System.Windows.Documents; 6 using System.Windows.Ink; 7 using System.Windows.Input; 8 using System.Windows.Media; 9 using System.Windows.Media.Animation; 10 using System.Windows.Shapes; 11 12 namespace WaterTextBox 13 { 14 public class WaterPasswordBox : TextBox 15 { 16 public static DependencyProperty WaterContentProprty = DependencyProperty.Register("WaterContent", typeof(object), typeof(WaterPasswordBox), new PropertyMetadata("水印密码框")); 17 18 public object WaterContent 19 { 20 get 21 { 22 return GetValue(WaterContentProprty); 23 } 24 25 set 26 { 27 SetValue(WaterContentProprty, value); 28 } 29 } 30 31 public static DependencyProperty WaterForegroundProprty = DependencyProperty.Register("WaterForeground", typeof(Brush), typeof(WaterPasswordBox), new PropertyMetadata(new SolidColorBrush(Colors.Gray))); 32 33 public Brush WaterForeground 34 { 35 get 36 { 37 return (Brush)GetValue(WaterForegroundProprty); 38 } 39 40 set 41 { 42 SetValue(WaterForegroundProprty, value); 43 } 44 } 45 46 public WaterPasswordBox() 47 { 48 DefaultStyleKey = typeof(WaterPasswordBox); 49 } 50 51 ContentControl WaterContentElement = null; 52 PasswordBox PasswordBoxElement = null; 53 54 public override void OnApplyTemplate() 55 { 56 base.OnApplyTemplate(); 57 WaterContentElement = this.GetTemplateChild("WaterCoElement") as ContentControl; 58 PasswordBoxElement = this.GetTemplateChild("ContentElement") as PasswordBox; 59 if (WaterContentElement != null && PasswordBoxElement != null) 60 { 61 PasswordBoxElement.PasswordChanged += new RoutedEventHandler(PasswordBoxElement_PasswordChanged); 62 if (string.IsNullOrEmpty(PasswordBoxElement.Password)) 63 WaterContentElement.Visibility = System.Windows.Visibility.Visible; 64 else 65 WaterContentElement.Visibility = System.Windows.Visibility.Collapsed; 66 } 67 } 68 69 void PasswordBoxElement_PasswordChanged(object sender, RoutedEventArgs e) 70 { 71 PasswordBox passwdBx = sender as PasswordBox; 72 this.Text = passwdBx.Password; 73 } 74 75 protected override void OnGotFocus(RoutedEventArgs e) 76 { 77 if (WaterContentElement != null && string.IsNullOrEmpty(PasswordBoxElement.Password)) 78 WaterContentElement.Visibility = Visibility.Collapsed; 79 base.OnGotFocus(e); 80 } 81 82 protected override void OnLostFocus(RoutedEventArgs e) 83 { 84 if (WaterContentElement != null && string.IsNullOrEmpty(PasswordBoxElement.Password)) 85 WaterContentElement.Visibility = Visibility.Visible; 86 base.OnLostFocus(e); 87 } 88 } 89 }
运行效果:
Ok搞定了,使用下还不错,不过PasswordBox的属性在WaterPasswordBox中无法使用。⊙﹏⊙b汗
Ps:如果你想让WaterPasswordBox和PasswordBox一样可以设置很多属性,那就开一些和WaterContent一样的依赖属性,或者你直接开一个Style属性吧。
源码下载:https://files.cnblogs.com/qq278360339/PhoneApp_water.zip
在wp8下上面的水印密码框有些不好用,所以重新写了下,下面附上代码。
1 <ResourceDictionary 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:CustomCtrlClassLibrary" 5 xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"> 6 7 <ControlTemplate x:Key="PhoneDisabledPasswordBoxTemplate" TargetType="PasswordBox"> 8 <Border x:Name="ContentElement" BorderThickness="0" Margin="{StaticResource PhonePasswordBoxInnerMargin}" Padding="{TemplateBinding Padding}"/> 9 </ControlTemplate> 10 <Style TargetType="local:MaskPasswordBox"> 11 <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/> 12 <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/> 13 <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/> 14 <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/> 15 <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/> 16 <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/> 17 <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/> 18 <Setter Property="SelectionForeground" Value="{StaticResource PhoneContrastBackgroundBrush}"/> 19 <Setter Property="Padding" Value="2"/> 20 <Setter Property="Template"> 21 <Setter.Value> 22 <ControlTemplate TargetType="local:MaskPasswordBox"> 23 <Grid Background="Transparent"> 24 <VisualStateManager.VisualStateGroups> 25 <VisualStateGroup x:Name="CommonStates"> 26 <VisualState x:Name="Normal"/> 27 <VisualState x:Name="MouseOver"/> 28 <VisualState x:Name="Disabled"> 29 <Storyboard> 30 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder"> 31 <DiscreteObjectKeyFrame KeyTime="0"> 32 <DiscreteObjectKeyFrame.Value> 33 <Visibility>Collapsed</Visibility> 34 </DiscreteObjectKeyFrame.Value> 35 </DiscreteObjectKeyFrame> 36 </ObjectAnimationUsingKeyFrames> 37 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledBorder"> 38 <DiscreteObjectKeyFrame KeyTime="0"> 39 <DiscreteObjectKeyFrame.Value> 40 <Visibility>Visible</Visibility> 41 </DiscreteObjectKeyFrame.Value> 42 </DiscreteObjectKeyFrame> 43 </ObjectAnimationUsingKeyFrames> 44 </Storyboard> 45 </VisualState> 46 </VisualStateGroup> 47 <VisualStateGroup x:Name="FocusStates"> 48 <VisualState x:Name="Focused"> 49 <Storyboard> 50 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="EnabledBorder"> 51 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/> 52 </ObjectAnimationUsingKeyFrames> 53 <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="EnabledBorder"> 54 <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/> 55 </ObjectAnimationUsingKeyFrames> 56 </Storyboard> 57 </VisualState> 58 <VisualState x:Name="Unfocused"/> 59 </VisualStateGroup> 60 </VisualStateManager.VisualStateGroups> 61 <Border x:Name="EnabledBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"> 62 <Grid> 63 <ContentControl x:Name="MarkContent" Style="{TemplateBinding MarkStyle}" Opacity="0.5" Background="Transparent" 64 Content="{TemplateBinding MaskContent}" Padding="{TemplateBinding Padding}" 65 HorizontalAlignment="{TemplateBinding MaskHorizontalAlignment}"/> 66 <PasswordBox x:Name="ContentElement" Background="Transparent" Template="{StaticResource PhoneDisabledPasswordBoxTemplate}" 67 Password="{TemplateBinding Text}" PasswordChar="{TemplateBinding PswdChar}"/> 68 </Grid> 69 </Border> 70 <Border x:Name="DisabledBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"> 71 <PasswordBox x:Name="DisabledContent" Background="Transparent" Foreground="{StaticResource PhoneDisabledBrush}" 72 Password="{TemplateBinding Text}" PasswordChar="{TemplateBinding PswdChar}" 73 Template="{StaticResource PhoneDisabledPasswordBoxTemplate}"/> 74 </Border> 75 </Grid> 76 </ControlTemplate> 77 </Setter.Value> 78 </Setter> 79 </Style> 80 81 </ResourceDictionary>
1 using System; 2 using System.Text; 3 using System.Windows; 4 using System.Threading.Tasks; 5 using System.Windows.Controls; 6 7 namespace CustomCtrlClassLibrary 8 { 9 public class MaskPasswordBox : TextBox 10 { 11 ContentControl Markcontent; 12 PasswordBox PswdBox; 13 bool IsOnrtime = true; 14 15 #region -------------------------------- Construct Fuction --------------------------------- 16 17 public MaskPasswordBox() { 18 DefaultStyleKey = typeof(MaskPasswordBox); 19 } 20 21 #endregion 22 23 #region ----------------------------- Custom DependencyProperty ---------------------------- 24 25 #region ------------- MaskContent ------------- 26 public static readonly DependencyProperty MaskContentProperty = 27 DependencyProperty.Register("MaskContent", typeof(object), typeof(MaskPasswordBox), 28 new PropertyMetadata(OnMaskContentPropertyChanged)); 29 public object MaskContent { 30 get { return base.GetValue(MaskContentProperty) as object; } 31 set { base.SetValue(MaskContentProperty, value); } 32 } 33 private static void OnMaskContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { 34 MaskPasswordBox maskPasswordBox = sender as MaskPasswordBox; 35 if (maskPasswordBox != null && maskPasswordBox.Markcontent != null) { 36 maskPasswordBox.DetermineWatermarkContentVisibility(); 37 } 38 } 39 private void DetermineWatermarkContentVisibility() { 40 if (string.IsNullOrEmpty(this.Text)) { 41 this.Markcontent.Visibility = Visibility.Visible; 42 } else { 43 this.Markcontent.Visibility = Visibility.Collapsed; 44 } 45 } 46 #endregion 47 48 #region -------------- MarkStyle -------------- 49 public static readonly DependencyProperty MarkStyleProperty = 50 DependencyProperty.Register("MarkStyle", typeof(Style), typeof(MaskPasswordBox), 51 null); 52 public Style MarkStyle { 53 get { return base.GetValue(MarkStyleProperty) as Style; } 54 set { base.SetValue(MarkStyleProperty, value); } 55 } 56 #endregion 57 58 #region ------- MaskHorizontalAlignment ------- 59 public static readonly DependencyProperty MaskHorizontalAlignmentProperty = 60 DependencyProperty.Register("MaskHorizontalAlignment", typeof(HorizontalAlignment), 61 typeof(MaskPasswordBox), new PropertyMetadata(HorizontalAlignment.Left)); 62 public HorizontalAlignment MaskHorizontalAlignment { 63 get { return (HorizontalAlignment)base.GetValue(MaskHorizontalAlignmentProperty); } 64 set { base.SetValue(MaskHorizontalAlignmentProperty, value); } 65 } 66 #endregion 67 68 #region --------------- PswdChar -------------- 69 public static readonly DependencyProperty PswdCharProperty = 70 DependencyProperty.Register("PswdChar", typeof(string), typeof(MaskPasswordBox), 71 new PropertyMetadata("●", OnPswdCharPropertyChanged)); 72 public string PswdChar { 73 get { return (string)base.GetValue(PswdCharProperty); } 74 set { base.SetValue(PswdCharProperty, value); } 75 } 76 private static void OnPswdCharPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { 77 if (args.OldValue != args.NewValue) { 78 MaskPasswordBox maskPasswordBox = sender as MaskPasswordBox; 79 if (maskPasswordBox != null) { 80 maskPasswordBox.DeterminePswdChar(args.NewValue); 81 } 82 } 83 } 84 private void DeterminePswdChar(object pwsdChar) { 85 if (PswdBox != null) { 86 if (pwsdChar is string) { 87 string str = (string)pwsdChar; 88 if (!string.IsNullOrEmpty(str)) { 89 PswdBox.PasswordChar = str[0]; 90 } 91 } else if (pwsdChar is char) { 92 PswdBox.PasswordChar = (char)pwsdChar; 93 } 94 } 95 } 96 #endregion 97 98 #endregion 99 100 #region ----------------------------- Override TextBox Fuction ----------------------------- 101 102 public override void OnApplyTemplate() { 103 base.OnApplyTemplate(); 104 this.Markcontent = this.GetTemplateChild("MarkContent") as ContentControl; 105 if (Markcontent != null) { 106 DetermineWatermarkContentVisibility(); 107 } 108 this.PswdBox = this.GetTemplateChild("ContentElement") as PasswordBox; 109 if (PswdBox != null) { 110 PswdBox.PasswordChanged += PswdBox_PasswordChanged; 111 } 112 } 113 114 void PswdBox_PasswordChanged(object sender, RoutedEventArgs e) { 115 PasswordBox pswd = sender as PasswordBox; 116 this.Text = pswd.Password; 117 } 118 119 protected override void OnGotFocus(RoutedEventArgs e) { 120 if (Markcontent != null && string.IsNullOrEmpty(this.Text)) { 121 this.Markcontent.Visibility = Visibility.Collapsed; 122 } 123 if (PswdBox != null && IsOnrtime) { 124 DeterminePswdChar(PswdChar); 125 IsOnrtime = false; 126 } 127 base.OnGotFocus(e); 128 } 129 130 protected override void OnLostFocus(RoutedEventArgs e) { 131 if (Markcontent != null && string.IsNullOrEmpty(this.Text)) { 132 this.Markcontent.Visibility = Visibility.Visible; 133 } 134 base.OnLostFocus(e); 135 } 136 137 #endregion 138 } 139 }
Ps:给大家介绍一个不错我wp论坛,卤面网