WPF中設定PasswordBox為空,背景為文字提示
阿新 • • 發佈:2019-01-23
繼上篇部落格textbox為空時,背景為文字提示,關於密碼框水印就不同於文字框了,可以寫個Brush就搞定,因為密碼框是沒有可以用於判斷輸入非空的依賴屬性的,
下面就說一下實現過程
1、新建一個類:PasswordBoxHelper.cs
<span style="font-family:KaiTi_GB2312;font-size:24px;">using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; namespace JfCooperate { public class PasswordBoxHelper { static bool isInistialised = false; public static string GetWatermark(DependencyObject obj) { return (string)obj.GetValue(WatermarkProperty); } public static void SetWatermark(DependencyObject obj, string value) { obj.SetValue(WatermarkProperty, value); } public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached("Watermark", typeof(string), typeof(PasswordBoxHelper), new UIPropertyMetadata(null, WatermarkChanged)); public static bool GetShowWatermark(DependencyObject obj) { return (bool)obj.GetValue(ShowWatermarkProperty); } public static void SetShowWatermark(DependencyObject obj, bool value) { obj.SetValue(ShowWatermarkProperty, value); } public static readonly DependencyProperty ShowWatermarkProperty = DependencyProperty.RegisterAttached("ShowWatermark", typeof(bool), typeof(PasswordBoxHelper), new UIPropertyMetadata(false)); static void WatermarkChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { var pwd = obj as PasswordBox; CheckShowWatermark(pwd); if (!isInistialised) { pwd.PasswordChanged += new RoutedEventHandler(pwd_PasswordChanged); pwd.Unloaded += new RoutedEventHandler(pwd_Unloaded); isInistialised = true; } } private static void CheckShowWatermark(PasswordBox pwd) { pwd.SetValue(PasswordBoxHelper.ShowWatermarkProperty, pwd.Password == string.Empty); } static void pwd_PasswordChanged(object sender, RoutedEventArgs e) { var pwd = sender as PasswordBox; CheckShowWatermark(pwd); } static void pwd_Unloaded(object sender, RoutedEventArgs e) { var pwd = sender as PasswordBox; pwd.PasswordChanged -= new RoutedEventHandler(pwd_PasswordChanged); } } } </span>
在App.xaml中這樣寫到:
那麼在frmLogin.xaml中的程式碼如下:<Application x:Class="JfCooperate.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="frmLogin.xaml" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" xmlns:local="clr-namespace:JfCooperate"> <Application.Resources> <ResourceDictionary> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> <!--顯示水印--> <!--水印是內建了一個TextBlock,用附加PasswordBoxHelper.Watermark設定水印內容,在觸發器中檢測,當TextBox中有輸入值,則隱藏水印的TextBlock--> <ControlTemplate x:Key="WatermarkedPasswordBoxTemplate" TargetType="{x:Type PasswordBox}"> <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true"> <Grid> <TextBlock Text="{Binding Path=(local:PasswordBoxHelper.Watermark), RelativeSource={RelativeSource TemplatedParent}}" Opacity=".5" FontWeight="Bold" Visibility="{Binding (local:PasswordBoxHelper.ShowWatermark), Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource TemplatedParent}}" /> <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Grid> </Microsoft_Windows_Themes:ListBoxChrome> <ControlTemplate.Triggers> <!--不可用--> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </ResourceDictionary> </Application.Resources> </Application>
在使用重構的PasswordBox的時候需要去引用一下:
<span style="font-family:KaiTi_GB2312;font-size:24px;"><span style="font-family: KaiTi_GB2312;font-size:24px;"> </span>xmlns:local="clr-namespace:JfCooperate"</span>
我寫的是示範的demo 所以名稱空間是JfCooperate<span style="font-family:KaiTi_GB2312;font-size:24px;"><Controls:MetroWindow x:Class="JfCooperate.frmLogin" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" xmlns:local="clr-namespace:JfCooperate" Title="登入" Height="351.02" Width="439.423" Background="#FFFFFF" WindowStartupLocation="CenterScreen"> <Grid Margin="0,0,2,0"> <Label Content="機房收費系統" HorizontalAlignment="Left" Margin="121,33,0,0" VerticalAlignment="Top" RenderTransformOrigin="-6.501,-0.77" FontSize="24" FontFamily="Microsoft YaHei Light"/> <PasswordBox Margin="74,162,92,120" x:Name="pwd" Width="263" Template="{StaticResource WatermarkedPasswordBoxTemplate}" local:PasswordBoxHelper.Watermark="請輸入密碼" HorizontalAlignment="Center" VerticalAlignment="Center" Height="38" /> </Grid> </Controls:MetroWindow></span>
效果如圖: