C# 在passwordbox的某些事件上显示密码字符

C# 在passwordbox的某些事件上显示密码字符,c#,windows-phone-7,xaml,user-interface,passwords,C#,Windows Phone 7,Xaml,User Interface,Passwords,我正在开发一个windows phone应用程序。我要求用户登录 在登录页面上,用户必须输入密码 现在我想要的是,我给用户一个复选框,当选中该复选框时,应该显示密码的字符 我没有在密码框中看到任何显示密码字符的属性 请提出一些方法 使用默认密码箱无法实现所需的功能 您可以在这里找到更多信息:不要认为使用PasswordBox可以做到这一点。。。这只是一个想法,但是你可以使用一个隐藏的文本框来实现同样的结果,当用户单击复选框时,你只需隐藏密码框并显示文本框;如果他再次单击,您将再次切换其可见性状态

我正在开发一个windows phone应用程序。我要求用户登录

在登录页面上,用户必须输入密码

现在我想要的是,我给用户一个复选框,当选中该复选框时,应该显示密码的字符

我没有在密码框中看到任何显示密码字符的属性


请提出一些方法

使用默认密码箱无法实现所需的功能


您可以在这里找到更多信息:

不要认为使用PasswordBox可以做到这一点。。。这只是一个想法,但是你可以使用一个隐藏的文本框来实现同样的结果,当用户单击复选框时,你只需隐藏密码框并显示文本框;如果他再次单击,您将再次切换其可见性状态,依此类推

编辑

这就是为什么

只需添加一个页面,将ContentPanel更改为StackPanel并添加以下XAML代码:

<PasswordBox x:Name="MyPasswordBox" Password="{Binding Text, Mode=TwoWay, ElementName=MyTextBox}"/>
<TextBox x:Name="MyTextBox" Text="{Binding Password, Mode=TwoWay, ElementName=MyPasswordBox}" Visibility="Collapsed" />
<CheckBox x:Name="ShowPasswordCharsCheckBox" Content="Show password" Checked="ShowPasswordCharsCheckBox_Checked" Unchecked="ShowPasswordCharsCheckBox_Unchecked" />

这工作很好,但是再多做一些工作,您就可以完全用MVVM完成这项工作了

您可以创建自己的控件,该控件继承自textbox,但在每个字符后,您都将其替换为*,并将真值存储在页面上的私有变量中。使用复选框,您可以切换文本框中的值是显示真值还是*值


这不是一个优雅的解决方案,也不是一个最佳实践,但是如果您愿意接受它,我认为它仍然是一个替代方案。

我创建了一个MVVM示例,我也在实际生活中使用它。请注意,PasswordBox.Password不是依赖属性,因此无法直接绑定。出于安全考虑,它是这样设计的,有关详细信息,请参见:

如果您仍然想这样做,您必须使用代码隐藏构建到视图模型的桥梁。我不提供转换器,因为您可能正在使用自己的转换器集。如果没有,请向谷歌咨询合适的实施方案

输入密码窗口.xaml

<Window x:Class="MyDemoApp.Controls.EnterPasswordWindow"
        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:MyDemoApp.Controls"
        mc:Ignorable="d" d:DataContext="{d:DesignInstance local:EnterPasswordViewModel}"
        WindowStartupLocation="CenterOwner" ResizeMode="NoResize" SizeToContent="WidthAndHeight"
        Title="Enter Password">
    <StackPanel Margin="4">
        <TextBlock Margin="4">Please enter a password:</TextBlock>
        <TextBox Margin="4" Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding ShowPassword, Converter={StaticResource BoolToVisibleConverter}}"/>
        <PasswordBox Margin="4" Name="PasswordBox" Visibility="{Binding ShowPassword, Converter={StaticResource BoolToHiddenConverter}}" PasswordChanged="PasswordBox_PasswordChanged"/>
        <CheckBox Margin="4" IsChecked="{Binding ShowPassword}">Show password</CheckBox>
        <DockPanel>
            <Button Margin="4" Width="150" Height="30" IsDefault="True" IsEnabled="{Binding Password, Converter={StaticResource StringIsNotNullOrEmptyConverter}}" Click="Button_Click">OK</Button>
            <Button Margin="4" Width="150" Height="30" IsCancel="True" HorizontalAlignment="Right">Cancel</Button>
        </DockPanel>
    </StackPanel>
</Window>

那篇文章已经很老了,现在还不能反映PasswordBox.Password的真正本质,因为现在这是一个依赖属性,所以你可以绑定到它!好吧,它不起作用,因为VS2015说,你不能绑定密码箱的密码:(是的,不再起作用了,也许可以用那种方式更新你的答案。为了完整的MVVM,你还应该使用
Visibility=“{Binding ShowPassword,Converter={StaticResource booltohidenconverter}”
或类似内容。不要在“代码隐藏”中设置可见性。相关文章介绍如何在WinForms中实现该可见性-WPF相关文章-
<Window x:Class="MyDemoApp.Controls.EnterPasswordWindow"
        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:MyDemoApp.Controls"
        mc:Ignorable="d" d:DataContext="{d:DesignInstance local:EnterPasswordViewModel}"
        WindowStartupLocation="CenterOwner" ResizeMode="NoResize" SizeToContent="WidthAndHeight"
        Title="Enter Password">
    <StackPanel Margin="4">
        <TextBlock Margin="4">Please enter a password:</TextBlock>
        <TextBox Margin="4" Text="{Binding Password, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding ShowPassword, Converter={StaticResource BoolToVisibleConverter}}"/>
        <PasswordBox Margin="4" Name="PasswordBox" Visibility="{Binding ShowPassword, Converter={StaticResource BoolToHiddenConverter}}" PasswordChanged="PasswordBox_PasswordChanged"/>
        <CheckBox Margin="4" IsChecked="{Binding ShowPassword}">Show password</CheckBox>
        <DockPanel>
            <Button Margin="4" Width="150" Height="30" IsDefault="True" IsEnabled="{Binding Password, Converter={StaticResource StringIsNotNullOrEmptyConverter}}" Click="Button_Click">OK</Button>
            <Button Margin="4" Width="150" Height="30" IsCancel="True" HorizontalAlignment="Right">Cancel</Button>
        </DockPanel>
    </StackPanel>
</Window>
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace MyDemoApp.Controls
{
    /// <summary>
    /// Interaction logic for EnterPasswordWindow.xaml
    /// </summary>
    public partial class EnterPasswordWindow : Window
    {
        public EnterPasswordWindow()
        {
            InitializeComponent();
            DataContext = ViewModel = new EnterPasswordViewModel();
            ViewModel.PropertyChanged += ViewModel_PropertyChanged;
        }

        public EnterPasswordViewModel ViewModel { get; set; }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
            Close();
        }

        private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (!mSuppressPropertyChangedEvent && e.PropertyName == nameof(ViewModel.Password))
            {
                PasswordBox.Password = ViewModel.Password;
            }
        }
        private bool mSuppressPropertyChangedEvent;
        private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
        {
            mSuppressPropertyChangedEvent = true;
            ViewModel.Password = ((PasswordBox)sender).Password;
            mSuppressPropertyChangedEvent = false;
        }
    }
}
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MyDemoApp.Controls
{
    public class EnterPasswordViewModel : INotifyPropertyChanged
    {
        public string Password
        {
            get => mPassword;
            set
            {
                if (mPassword != value)
                {
                    mPassword = value;
                    NotifyPropertyChanged();
                }
            }
        }
        private string mPassword;

        public bool ShowPassword
        {
            get => mShowPassword;
            set
            {
                if (mShowPassword != value)
                {
                    mShowPassword = value;
                    NotifyPropertyChanged();
                }
            }
        }
        private bool mShowPassword;

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName]string propertyName = null)
        {
            if (string.IsNullOrEmpty(propertyName))
            {
                return;
            }
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}