C# Wpf直接调用PasswordBox简单实现显示明文(一)

一、属性样式及资源定义

1、加载静态图标

 2、定义ToggleButtonStyle样式

<!-- 图标控件预置属性及模板相关样式 -->
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
		<Setter Property="Margin" Value="5,0" />
		<Setter Property="Background" Value="Transparent" />
		<Setter Property="BorderThickness" Value="0" />
		<Setter Property="Template">
				<Setter.Value>
						<ControlTemplate TargetType="ToggleButton">
								<Image x:Name="IconImage" Source="./Resources/eye_close.png" />
								<ControlTemplate.Triggers>
										<Trigger Property="IsChecked" Value="True">
												<Setter TargetName="IconImage" Property="Source" Value="./Resources/eye_open.png" />
										</Trigger>

								</ControlTemplate.Triggers>
						</ControlTemplate>
				</Setter.Value>
		</Setter>
</Style>

二、PasswordBox实现

1、预置属性及模板相关样式

<Style TargetType="PasswordBox">
		<Setter Property="VerticalContentAlignment" Value="Center" />
		<Setter Property="Padding" Value="5,0" />
		<Setter Property="Template">
				<Setter.Value>
						<ControlTemplate TargetType="PasswordBox">
								<Border Background="{TemplateBinding Background}"
												BorderBrush="{TemplateBinding BorderBrush}"
												BorderThickness="{TemplateBinding BorderThickness}"
												CornerRadius="4">
										<Grid>
												<Grid.ColumnDefinitions>
														<ColumnDefinition Width="*" />
														<ColumnDefinition Width="32" />
												</Grid.ColumnDefinitions>

												<ScrollViewer Grid.Column="0" Name="PART_ContentHost"></ScrollViewer>
												<TextBlock Grid.Column="0" x:Name="MessageTextBlock"
												Text="{TemplateBinding Tag}"
												FontSize="{TemplateBinding FontSize}"
												Foreground="{TemplateBinding Foreground}"
												Padding="{TemplateBinding Padding}"
												VerticalAlignment="Center"
												Visibility="Hidden"></TextBlock>

												<!-- Text:对PasswordBox对象Password密文属性进行绑定 -->
												<!-- MaxLength:对PasswordBox对象MaxLength长度属性进行绑定-->
												<TextBox Grid.Column="0" VerticalContentAlignment="Center"
																	BorderThickness="0" Visibility="Hidden"
																	FontSize="{TemplateBinding FontSize}"
																	Foreground="{TemplateBinding Foreground}"
																	Padding="{TemplateBinding Padding}"
																	Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=PasswordBox},Path=(local:PasswordBoxAttached.Password)}"
																	MaxLength="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=PasswordBox},Path=(PasswordBox.MaxLength)}" 
																	x:Name="PasswordTextBox"></TextBox>
												<!-- 图标控件 -->
												<ToggleButton Grid.Column="1" x:Name="CheckedToggleButton" Focusable="False"
																			Style="{StaticResource ToggleButtonStyle}"></ToggleButton>
										</Grid>
								</Border>

								<ControlTemplate.Triggers>
										<MultiTrigger>
												<MultiTrigger.Conditions>
														<Condition Property="IsKeyboardFocused" Value="False"></Condition>
														<Condition Property="local:PasswordBoxAttached.Password" Value=""></Condition>
												</MultiTrigger.Conditions>

												<Setter TargetName="MessageTextBlock" Property="Visibility" Value="Visible"></Setter>
												<Setter TargetName="MessageTextBlock" Property="Opacity" Value="0.5"></Setter>
										</MultiTrigger>

										<DataTrigger Binding="{Binding ElementName=CheckedToggleButton,Path=IsChecked}" Value="True">
												<Setter TargetName="PasswordTextBox" Property="Visibility" Value="Visible"></Setter>
												<Setter TargetName="PART_ContentHost" Property="Visibility" Value="Hidden"></Setter>
										</DataTrigger>
								</ControlTemplate.Triggers>
						</ControlTemplate>
				</Setter.Value>
		</Setter>
</Style>

此处,传递的相关属性如下:

  • TextBox.Text属性:绑定PasswordBoxAttached.Password依赖属性
  • TextBox.MaxLength属性:绑定PasswordBox.MaxLength属性

这里笔者用到了MultiTrigger属性发生变化条件触发器以及数据发生变化条件触发器进行密文及明文的切换过程实现。

2、依赖属性的定义

public class PasswordBoxAttached
{
		/// <summary>
		/// 密文内容属性
		/// </summary>
		public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached(
				"Password", typeof(string), typeof(PasswordBoxAttached),
				new PropertyMetadata("", PasswordPropertyChangedCallback));

		/// <summary>
		/// Get密文字段
		/// </summary>
		[AttachedPropertyBrowsableForType(typeof(PasswordBox))]
		public static string GetPassword(DependencyObject obj)
		{
				return (string)obj.GetValue(PasswordProperty);
		}

		/// <summary>
		/// Set密文字段
		/// </summary>
		public static void SetPassword(DependencyObject obj, string value)
		{
				obj.SetValue(PasswordProperty, value);
		}

		/// <summary>
		/// 密文回调事件
		/// </summary>
		/// <param name="d"></param>
		/// <param name="e"></param>
		private static void PasswordPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
				if (d is PasswordBox pb)
				{
						pb.Password = e.NewValue.ToString();
						pb.GetType().GetMethod("Select",
								BindingFlags.Instance | BindingFlags.NonPublic).Invoke(pb, new object[] { pb.Password.Length, 0 });
				}
		}
}

3、场景应用

(1)  XAML前端

<Window x:Class="WpfAppDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfAppDemo"
        mc:Ignorable="d"
        WindowStyle="None" WindowStartupLocation="CenterScreen"
        AllowsTransparency="True" Background="Transparent"
        Title="MainWindow" Height="200" Width="350" >

<Border BorderBrush="#20333333" BorderThickness="1" CornerRadius="8" Background="White" Margin="0">
		<Border.Effect>
				<DropShadowEffect BlurRadius="8" Color="#20333333" ShadowDepth="0"></DropShadowEffect>
		</Border.Effect>
		<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
				<TextBlock Text="密码:" Padding="0,10,0,10" HorizontalAlignment="Center" VerticalAlignment="Center" />
				<PasswordBox x:Name="tBoxPwd" HorizontalAlignment="Center" VerticalAlignment="Center" MaxLength="10"
											Width="120" PasswordChanged="LoginPasswordBox_OnPasswordChanged" />
		</StackPanel>
</Border>

</Window>

(2) 内容发生改变事件

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
		//private readonly PasswordBoxViewModel PwdViewModel;

		public MainWindow()
		{
				InitializeComponent();
				//PwdViewModel = new PasswordBoxViewModel();
				//DataContext = PwdViewModel;
		}

		/// <summary>
		/// 明文显示
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void LoginPasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
		{
				if (sender is PasswordBox pb)
				{
						PasswordBoxAttached.SetPassword(pb, pb.Password);
				}
		}
}

最终效果:

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值