【问题标题】:showing password characters on some event for passwordbox在密码框的某些事件上显示密码字符
【发布时间】:2012-04-22 21:41:24
【问题描述】:

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

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

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

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

请提出一些方法来做到这一点。

【问题讨论】:

标签: c# windows-phone-7 xaml user-interface passwords


【解决方案1】:

使用默认密码框无法实现您想要的功能。

您可以在这里找到更多信息:http://social.msdn.microsoft.com/Forums/en/wpf/thread/98d0d4d4-1463-481f-b8b1-711119a6ba99

【讨论】:

  • 那篇文章很老了,现在还不能反映 PasswordBox.Password 的真实性质,因为现在这是一个依赖属性,所以你可以绑定到它!
【解决方案2】:

不要认为 PasswordBox 是可能的...只是一个想法,但是您可以使用隐藏的 TextBox 来实现相同的结果,当用户单击 CheckBox 时,您只需隐藏 PasswordBox 并显示 TextBox;如果他再次点击,您将再次切换其可见性状态,依此类推...

编辑

这就是方法!

只需添加一个页面,将 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" />

接下来,在页面代码上,添加以下内容:

private void ShowPasswordCharsCheckBox_Checked(object sender, RoutedEventArgs e)
{
    MyPasswordBox.Visibility = System.Windows.Visibility.Collapsed;
    MyTextBox.Visibility = System.Windows.Visibility.Visible;

    MyTextBox.Focus();
}

private void ShowPasswordCharsCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
    MyPasswordBox.Visibility = System.Windows.Visibility.Visible;
    MyTextBox.Visibility = System.Windows.Visibility.Collapsed;

    MyPasswordBox.Focus();
}

这工作正常,但再做一些工作,你就可以做到这一点完全 MVVM'ed!

【讨论】:

  • 嗯,不行,因为VS2015说,不能绑定密码框的密码:(
  • 是的,不再工作了,也许以这种方式更新你的答案。
  • 对于完整的 MVVM'iness,您还应该使用 Visibility="{Binding ShowPassword, Converter={StaticResource BoolToHiddenConverter}}" 或类似名称。不要在后面的代码中设置可见性。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    我创建了一个 MVVM 示例,我也在现实生活中使用它。请注意 PasswordBox.Password 不是依赖属性,因此不能直接绑定。出于安全原因,它是这样设计的,详情请参阅:How to bind to a PasswordBox in MVVM

    无论如何,如果你想这样做,你必须使用后面的代码来建立你的视图模型的桥梁。我不提供转换器,因为您可能正在使用自己的一组转换器。如果没有,请向 google 寻求合适的实现。

    EnterPasswordWindow.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 BoolToCollapsedConverter}}" 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>
    

    EnterPasswordWindow.xaml.cs

    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;
            }
        }
    }
    

    EnterPasswordViewModel.cs

    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));
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 2011-12-31
      • 2010-11-24
      • 2017-08-22
      • 2023-04-03
      相关资源
      最近更新 更多