WPF PasswordBox样式(占位符,清除按钮 )

来源:互联网 发布:java hadoop 读取文件 编辑:程序博客网 时间:2024/06/08 15:33

有些部分是从别人那拿过来的。

效果:


Style:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                    xmlns:controls="clr-namespace:ImageButtonTest01.Control"                    xmlns:local="clr-namespace:ImageButtonTest01.Themes"                    xmlns:converter="clr-namespace:ImageButtonTest01.Control.Converter">    <converter:ImageTextBoxMarginLeftConverter x:Key="ITBMLC"/>    <converter:PlaceholderFontSizeConverter x:Key="PHFSC"/>    <converter:ClearButtonEnableTester x:Key="CBET"/>    <SolidColorBrush x:Key="PasswordBox.Static.Foreground" Color="Black"/>    <SolidColorBrush x:Key="PasswordBox.Static.Background" Color="Transparent"/>    <SolidColorBrush x:Key="PasswordBox.Static.SelectionBrush" Color="#808F8787"/>    <SolidColorBrush x:Key="PasswordBox.Static.BorderBrush" Color="#FF909090"/>    <SolidColorBrush x:Key="PasswordBox.Focused.BorderBrush" Color="#FF007ACC"/>    <SolidColorBrush x:Key="PasswordBox.MouseOver.BorderBrush" Color="#FF1E1E1E"/>    <Style TargetType="{x:Type PasswordBox}" x:Key="DefaultPasswordBox">        <Setter Property="SelectionBrush" Value="{StaticResource PasswordBox.Static.SelectionBrush}"/>        <Setter Property="Padding" Value="0"/>        <Setter Property="FontSize" Value="22"/>        <Setter Property="BorderThickness" Value="2"/>        <Setter Property="PasswordChar" Value="●"/>        <Setter Property="Background" Value="{StaticResource PasswordBox.Static.Background}"/>        <Setter Property="Foreground" Value="{StaticResource PasswordBox.Static.Foreground}"/>        <Setter Property="BorderBrush" Value="{StaticResource PasswordBox.Static.BorderBrush}"/>        <Setter Property="VerticalContentAlignment" Value="Center"/>        <Setter Property="SnapsToDevicePixels" Value="True" />        <Setter Property="CaretBrush" Value="{StaticResource PasswordBox.Static.Foreground}"/>        <Setter Property="controls:PasswordBoxHelper.Attach" Value="True"/>        <Setter Property="controls:PasswordBoxHelper.Password" Value="{Binding Path=Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>        <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="{x:Type PasswordBox}">                    <Border x:Name="PART_Root" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"                            CornerRadius="{TemplateBinding controls:ControlAttachProperty.CornerRadius}"                            BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"                            Background="{TemplateBinding Background}">                        <Grid x:Name="PART_InnerGrid">                            <Grid.ColumnDefinitions>                                <ColumnDefinition Width="{Binding Path=(controls:ControlAttachProperty.CornerRadius).TopLeft, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ITBMLC}}"/>                                <ColumnDefinition Width="*"/>                                <ColumnDefinition  Width="Auto"/>                                <ColumnDefinition  Width="Auto"/>                            </Grid.ColumnDefinitions>                            <!--内容区域-->                            <ScrollViewer x:Name="PART_ContentHost" Grid.Column="1" Margin="2"                                          BorderThickness="0" IsTabStop="False"                                          VerticalAlignment="Stretch" Background="{x:Null}"                                          VerticalContentAlignment="Center"/>                            <TextBlock x:Name="PART_PlaceHolder" Grid.Column="1" Foreground="Black"                                       IsHitTestVisible="False" Margin="3,0,3,0"                                       HorizontalAlignment="Left" VerticalAlignment="Center"                                       SnapsToDevicePixels="True"                                       Visibility="Collapsed" Opacity="0.6"                                       TextAlignment="Center"                                       Text="{Binding Path=(controls:ControlAttachProperty.PlaceHolder), RelativeSource={RelativeSource TemplatedParent}}"                                       FontSize="{Binding FontSize, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource PHFSC}}"/>                            <!--附加内容区域-->                            <!--<Border x:Name="PART_AttachContent" Grid.Column="2" Margin="1"                                    HorizontalAlignment="Center" VerticalAlignment="Center">                                <ContentControl VerticalAlignment="Center" VerticalContentAlignment="Center"                                                Template="{TemplateBinding controls:ControlAttachProperty.AttachContent}"/>                            </Border>-->                            <controls:ImageButton x:Name="PART_ClearTextButton" IsTabStop="False" Grid.Column="2"                                          controls:ControlAttachProperty.IsClearButtonEnabled="True"                                          FontFamily="/ImageButtonTest01;component/Resources/#iconfont"                                          Content="" FontSize="20" IsEnabled="True"                                          HorizontalAlignment="Right"                                          VerticalAlignment="Center"                                          Command="controls:ControlAttachProperty.ClearTextCommand"                                          CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type PasswordBox}}}"                                          Style="{StaticResource ImageButtonTransparent}"/>                        </Grid>                    </Border>                    <ControlTemplate.Triggers>                        <!--<DataTrigger Binding="{Binding Path=controls:PasswordBoxHelper.Password, RelativeSource={RelativeSource TemplatedParent}}" Value="">                            <Setter TargetName="PART_PlaceHolder" Property="Visibility" Value="Visible"/>                        </DataTrigger>-->                        <Trigger Property="controls:PasswordBoxHelper.Password"  Value="">                            <Setter TargetName="PART_PlaceHolder" Property="Visibility" Value="Visible"/>                            <Setter TargetName="PART_ClearTextButton" Property="IsEnabled" Value="False"/>                        </Trigger>                        <Trigger Property="IsMouseOver" Value="True">                            <Setter  Property="BorderBrush" Value="{StaticResource PasswordBox.MouseOver.BorderBrush}"/>                        </Trigger>                        <Trigger Property="IsFocused" Value="True">                            <Setter  Property="BorderBrush" Value="{StaticResource PasswordBox.Focused.BorderBrush}"/>                        </Trigger>                        <Trigger Property="IsEnabled" Value="False">                            <Setter TargetName="PART_Root" Property="Opacity" Value="0.4"/>                        </Trigger>                    </ControlTemplate.Triggers>                </ControlTemplate>            </Setter.Value>        </Setter>    </Style>    <Style x:Key="ClearButtonPasswordBox" TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource DefaultPasswordBox}">        <Setter Property="controls:ControlAttachProperty.AttachContent">            <Setter.Value>                <ControlTemplate>                    <!--<controls:ImageButton x:Name="PART_ClearTextButton" IsTabStop="False"                                          controls:ControlAttachProperty.IsClearButtonEnabled="True"                                          FontFamily="/ImageButtonTest01;component/Resources/#iconfont"                                          Content="" FontSize="20"                                          HorizontalAlignment="Right"                                          VerticalAlignment="Center"                                          Command="controls:ControlAttachProperty.ClearTextCommand"                                          CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type PasswordBox}}}"                                          Style="{StaticResource ImageButtonTransparent}">                        <controls:ImageButton.IsEnabled>                            <MultiBinding Converter="{StaticResource CBET}">                                <Binding Path="controls:PasswordBoxHelper.Password" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type PasswordBox}}"/>                            </MultiBinding>                        </controls:ImageButton.IsEnabled>                    </controls:ImageButton>-->                </ControlTemplate>            </Setter.Value>        </Setter>    </Style></ResourceDictionary>

ControlAttachProperty.cs别人的(解决PasswordBox不能被继承敲打

public static class ControlAttachProperty{    static ControlAttachProperty()    {        /* ClearTextCommand */        ClearTextCommand = new RoutedUICommand();        ClearTextCommandBinding = new CommandBinding(ClearTextCommand);        ClearTextCommandBinding.Executed += ClearButtonClick;    }    public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius),                                                                                typeof(ControlAttachProperty), new FrameworkPropertyMetadata(new CornerRadius(0,0,0,0)));    public static CornerRadius GetCornerRadius(DependencyObject d)    {        return (CornerRadius)d.GetValue(CornerRadiusProperty);    }    public static void SetCornerRadius(DependencyObject d, CornerRadius value)    {        d.SetValue(CornerRadiusProperty, value);    }    #region PlaceHolderProperty 占位符    public static readonly DependencyProperty PlaceHolderProperty = DependencyProperty.RegisterAttached("PlaceHolder", typeof(string),                                                         typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));    public static string GetPlaceHolder(DependencyObject d)    {        return (string)d.GetValue(PlaceHolderProperty);    }    public static void SetPlaceHolder(DependencyObject obj, string value)    {        obj.SetValue(PlaceHolderProperty, value);    }    #endregion    public static readonly DependencyProperty AttachContentProperty = DependencyProperty.RegisterAttached("AttachContent", typeof(ControlTemplate),                                                             typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));    public static ControlTemplate GetAttachContent(DependencyObject d)    {        return (ControlTemplate)d.GetValue(AttachContentProperty);    }    public static void SetAttachContent(DependencyObject obj, ControlTemplate value)    {        obj.SetValue(AttachContentProperty, value);    }    #region ClearTextCommand 清除输入框Text事件命令    /// <summary>    /// 清除输入框Text事件命令,需要使用IsClearTextButtonBehaviorEnabledChanged绑定命令    /// </summary>    public static RoutedUICommand ClearTextCommand { get; private set; }    /// <summary>    /// ClearTextCommand绑定事件    /// </summary>    private static readonly CommandBinding ClearTextCommandBinding;    /// <summary>    /// 清除输入框文本值    /// </summary>    private static void ClearButtonClick(object sender, ExecutedRoutedEventArgs e)    {        var tbox = e.Parameter as FrameworkElement;        if (tbox == null)        {            return;        }        if (tbox is TextBox)        {            ((TextBox)tbox).Clear();        }        else if (tbox is PasswordBox)        {            ((PasswordBox)tbox).Clear();        }        else if (tbox is ComboBox)        {            var cb = tbox as ComboBox;            cb.SelectedItem = null;            cb.Text = string.Empty;        }        else if (tbox is DatePicker)        {            var dp = tbox as DatePicker;            dp.SelectedDate = null;            dp.Text = string.Empty;        }        tbox.Focus();    }    #endregion    #region IsClearTextButtonBehaviorEnabledProperty 清除输入框Text值按钮行为开关(设为ture时才会绑定事件)    /// <summary>    /// 清除输入框Text值按钮行为开关    /// </summary>    public static readonly DependencyProperty IsClearButtonEnabledProperty = DependencyProperty.RegisterAttached("IsClearButtonEnabled", typeof(bool),                     typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsClearButtonEnabledChanged));    [AttachedPropertyBrowsableForType(typeof(TextBox))]    public static bool GetIsClearButtonEnabled(DependencyObject d)    {        return (bool)d.GetValue(IsClearButtonEnabledProperty);    }    public static void SetIsClearButtonEnabled(DependencyObject obj, bool value)    {        obj.SetValue(IsClearButtonEnabledProperty, value);    }    /// <summary>    /// 绑定清除Text操作的按钮事件    /// </summary>    private static void IsClearButtonEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)    {        var button = d as ImageButton;        if ((null != button) && (e.OldValue != e.NewValue))        {            button.CommandBindings.Add(ClearTextCommandBinding);        }    }    #endregion}

PasswordBoxHelper.cs别人的,主要解决PasswordBox的Password不是依赖属性问题

public static class PasswordBoxHelper{    static PasswordBoxHelper()    {    }    public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached("Attach", typeof(bool),                                                    typeof(PasswordBoxHelper), new PropertyMetadata(false, AttachToPasswordBox));    public static bool GetAttach(DependencyObject dp)    {        return (bool)dp.GetValue(AttachProperty);    }    public static void SetAttach(DependencyObject dp, bool value)    {        dp.SetValue(AttachProperty, value);    }    public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string),                                                    typeof(PasswordBoxHelper), new FrameworkPropertyMetadata("", OnPasswordPropertyChanged));    public static string GetPassword(DependencyObject dp)    {        return (string)dp.GetValue(PasswordProperty);    }    public static void SetPassword(DependencyObject dp, string value)    {        dp.SetValue(PasswordProperty, value);    }    private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), typeof(PasswordBoxHelper));    private static bool GetIsUpdating(DependencyObject dp)    {        return (bool)dp.GetValue(IsUpdatingProperty);    }    private static void SetIsUpdating(DependencyObject dp, bool value)    {        dp.SetValue(IsUpdatingProperty, value);    }    private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)    {        PasswordBox passwordBox = sender as PasswordBox;        passwordBox.PasswordChanged -= PasswordChanged;        if (!(bool)GetIsUpdating(passwordBox))        {            passwordBox.Password = (string)e.NewValue;        }        passwordBox.PasswordChanged += PasswordChanged;    }    private static void AttachToPasswordBox(DependencyObject sender, DependencyPropertyChangedEventArgs e)    {        PasswordBox passwordBox = sender as PasswordBox;        if (null == passwordBox)        {            return;        }        if ((bool)e.OldValue)        {            passwordBox.PasswordChanged -= PasswordChanged;        }        if ((bool)e.NewValue)        {            passwordBox.PasswordChanged += PasswordChanged;        }    }    private static void PasswordChanged(object sender, RoutedEventArgs e)    {        PasswordBox passwordBox = sender as PasswordBox;        SetIsUpdating(passwordBox, true);        SetPassword(passwordBox, passwordBox.Password);        SetIsUpdating(passwordBox, false);    }}

ImageTextBoxMarginLeftConverter.cs

public class ImageTextBoxMarginLeftConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        if (value is double)        {            double v = (double)value;            if (null != parameter)            {                return v * double.Parse(parameter.ToString());            }            return v * 2.0 / 5.0;        }        return 0;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}

PlaceholderFontSizeConverter.cs

public class PlaceholderFontSizeConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        double v = (double)value;        return (v * 3.5) / 5.0;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}


使用:

<StackPanel Grid.Row="3" Orientation="Horizontal">    <PasswordBox x:Name="usrPassword" Width="150" Height="40"        Style="{StaticResource ClearButtonPasswordBox}"                    Margin="3"                    control:ControlAttachProperty.PlaceHolder="请输入密码"/>    <PasswordBox x:Name="usrPassword1" Width="150" Height="40"        Style="{StaticResource ClearButtonPasswordBox}"                    PasswordChar="*" Margin="3"                    control:ControlAttachProperty.PlaceHolder="请输入密码"                    IsEnabled="False"/>    <PasswordBox x:Name="usrPassword2" Width="150" Height="40"        Style="{StaticResource ClearButtonPasswordBox}"                    PasswordChar="*" Margin="3"                    control:ControlAttachProperty.PlaceHolder="请输入密码"                    control:ControlAttachProperty.CornerRadius="10"                    IsEnabled="True"/></StackPanel>