TextBox and PasswordBox watermark Effect of WPF, wpfpasswordbox
I saw a lot of articles on the text box and Password box watermark effect in my blog. Today I am free to implement it. The final result is as follows:
The Text field can be directly bound to its Text attribute. Because it is a dependency attribute, I use two methods to achieve the watermark effect: trigger and data binding;
I. Trigger method:
<! -- Watermark effect in the form of a trigger --> <Style x: key = "TxbTrigger" TargetType = "TextBox" BasedOn = "{StaticResource TxbBase}"> <Setter Property = "Template"> <Setter. value> <ControlTemplate TargetType = "TextBox"> <Border x: name = "border" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}" Background = "{TemplateBinding Background}" Background = "True"> <Grid> <ScrollViewer x: name = "PART_ContentHost" Focusable = "False" HorizontalScrollBarVisibility = "Hidden" VerticalScrollBarVisibility = "Hidden"/> <TextBlock x: name = "WaterMark" Focusable = "False" Visibility = "Collapsed" Text = "{TemplateBinding Tag}" verticalignment = "{TemplateBinding rating}" Opacity = "0.5"/> </ grid> </Border> <ControlTemplate. triggers> <Trigger Property = "IsEnabled" Value = "False"> <Setter Property = "Opacity" TargetName = "border" Value = "0.56"/> </Trigger> <Trigger property = "IsMouseOver" Value = "True"> <Setter Property = "BorderBrush" TargetName = "border" Value = "# FF7EB4EA"/> </Trigger> <Trigger Property =" isKeyboardFocused "Value =" True "> <Setter Property =" BorderBrush "TargetName =" border "Value =" # ff1_de5 "/> </Trigger> <Trigger Property =" Text "Value = ""> <Setter Property = "Visibility" TargetName = "WaterMark" Value = "Visibility"/> </Trigger> </ControlTemplate. triggers> </ControlTemplate> </Setter. value> </Setter> </Style>
Ii. Data Binding method
<! -- Bind and transformer the watermark effect --> <Style x: key = "TxbBing" TargetType = "TextBox" BasedOn = "{StaticResource TxbBase}"> <Setter Property = "Template"> <Setter. value> <ControlTemplate TargetType = "TextBox"> <Border x: name = "border" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}" Background = "{TemplateBinding Background}" Background = "True"> <Grid> <ScrollViewer x: name = "PART_ContentHost" Focusable = "False" HorizontalScrollBarVisibility = "Hidden" VerticalScrollBarVisibility = "Hidden"/> <TextBlock x: name = "WaterMark" Focusable = "False" Visibility = "{TemplateBinding Text, converter = {StaticResource TextToVisibility} "Text =" {TemplateBinding Tag} "verticalignment =" {TemplateBinding encoding} "Opacity =" 0.5 "/> </Grid> </Border> <controlTemplate. triggers> <Trigger Property = "IsEnabled" Value = "False"> <Setter Property = "Opacity" TargetName = "border" Value = "0.56"/> </Trigger> <Trigger property = "IsMouseOver" Value = "True"> <Setter Property = "BorderBrush" TargetName = "border" Value = "# FF7EB4EA"/> </Trigger> <Trigger Property =" isKeyboardFocused "Value =" True "> <Setter Property =" BorderBrush "TargetName =" border "Value =" # ff1_de5 "/> </Trigger> </ControlTemplate. triggers> </ControlTemplate> </Setter. value> </Setter> </Style>
The watermark effect of the Password box is a little more troublesome, because this Password is not dependent on the property, so it cannot be bound like the Text of the TextBox; this is implemented through the form of additional properties;
The Code is as follows:
/// <Summary> /// add watermark helper class to PasswordBox /// </summary> public class PasswordBoxWaterMark: DependencyObject {public static bool GetIsMonitoring (DependencyObject obj) {return (bool) obj. getValue (IsMonitoringProperty);} public static void SetIsMonitoring (DependencyObject obj, bool value) {obj. setValue (IsMonitoringProperty, value);} public static readonly DependencyProperty IsMonitoringProperty = DependencyProperty. registerAttached ("IsMonitoring", typeof (bool), typeof (PasswordBoxWaterMark), new evaluate (false, OnIsMonitoringChanged); public static int GetPasswordLength (DependencyObject obj) {return (int. getValue (PasswordLengthProperty);} public static void SetPasswordLength (DependencyObject obj, int value) {obj. setValue (PasswordLengthProperty, value);} public static readonly DependencyProperty PasswordLengthProperty = DependencyProperty. registerAttached ("PasswordLength", typeof (int), typeof (PasswordBoxWaterMark), new UIPropertyMetadata (0); private static void OnIsMonitoringChanged (DependencyObject d, ipve) {var pb = d as PasswordBox; if (pb = null) {return;} if (bool) e. newValue) {pb. passwordChanged + = PasswordChanged;} else {pb. passwordChanged-= PasswordChanged;} private static void PasswordChanged (object sender, RoutedEventArgs e) {var pb = sender as PasswordBox; if (pb = null) {return ;} setPasswordLength (pb, pb. password. length );}}
The PasswordBox style is as follows:
<Style TargetType = "PasswordBox"> <Setter Property = "Foreground" Value = "Red"/> <Setter Property = "FontSize" Value = "20"/> <! -- Color of the cursor --> <Setter Property = "CaretBrush" Value = "Green"/> <Setter Property = "Core: PasswordBoxWaterMark. isMonitoring "Value =" true "/> <Setter Property =" Template "> <Setter. value> <ControlTemplate TargetType = "{x: Type PasswordBox}"> <Border x: name = "border" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}" Background = "{TemplateBinding Background}" Background = "True"> <Grid> <ScrollViewer x: name = "PART_ContentHost" Focusable = "False" HorizontalScrollBarVisibility = "Hidden" VerticalScrollBarVisibility = "Hidden"/> <TextBlock x: name = "WaterMark" Focusable = "False" Visibility = "Collapsed" Text = "{TemplateBinding Tag}" verticalignment = "{TemplateBinding rating}" Opacity = "0.5"/> </ grid> </Border> <ControlTemplate. triggers> <Trigger Property = "Core: PasswordBoxWaterMark. passwordLength "Value =" 0 "> <Setter TargetName =" WaterMark "Property =" Visibility "Value =" Visible "/> </Trigger> </ControlTemplate. triggers> </ControlTemplate> </Setter. value> </Setter> </Style>
Source code: Demo. Zip