1. 程式人生 > >WPF中設定PasswordBox為空,背景為文字提示

WPF中設定PasswordBox為空,背景為文字提示

    繼上篇部落格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中這樣寫到:

<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>
那麼在frmLogin.xaml中的程式碼如下:

在使用重構的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>

效果如圖: