wpf 设置 PasswordBox 的初始值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32089243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:21:06  来源:igfitidea点击:

Setting initial value of PasswordBox

c#wpfwpf-controlspasswordbox

提问by 537mfb

I'm wondering if this is at all possible with all the security involved with the PasswordBox control:

我想知道 PasswordBox 控件涉及的所有安全性是否完全可能:

I have a XAML form (C#/WPF) where users will configure a database access. In that form i'm using a PasswordBox to get the SQL Server user password.

我有一个 XAML 表单(C#/WPF),用户将在其中配置数据库访问。在这种形式中,我使用 PasswordBox 来获取 SQL Server 用户密码。

Since this data is saved to disk for future use (in a pasword protected SQL Server CE database file), while on first run there is no password set, if the user comes back and needs to edit the SQL connection for some reason, then there could be a password kept from the previous configuration (unless he used Windows Authentication rather than SQL User Authentication)

由于这些数据被保存到磁盘以备将来使用(在受密码保护的 SQL Server CE 数据库文件中),而在第一次运行时没有设置密码,如果用户回来并出于某种原因需要编辑 SQL 连接,那么可能是从以前的配置中保留的密码(除非他使用 Windows 身份验证而不是 SQL 用户身份验证)

So I want to show an empty PasswordBox on the first run but if there's a password set already, when the user returns I want to show X number of '*' (to give indication that there is a password in place.

所以我想在第一次运行时显示一个空的 PasswordBox 但如果已经设置了密码,当用户返回时我想显示 X 个“*”(以表明存在密码。

Since PasswordBox.Password isn't bindable, I can only choose to always show it empty or always show a fixed number of '*' (by setting a default Password that doesn't actually represent the real password).

由于 PasswordBox.Password 不可绑定,我只能选择始终将其显示为空或始终显示固定数量的“*”(通过设置实际上并不代表真实密码的默认密码)。

Is there any alternative (besides something like the PasswordBox Helper that injects binding of course - i'd rather not go that path as there might be a reason i haven't considered for MS to choose not to make it bindable even to a SecureString)?

有没有其他选择(除了像 PasswordBox Helper 这样当然注入绑定的东西 - 我宁愿不走那条路,因为可能有一个我没有考虑过让 MS 选择不让它绑定到 SecureString 的原因) ?

回答by Mohit Shrivastava

You can read the Password from the file.

您可以从文件中读取密码。

//Storing the Password in String.
string pwd = "Password Read from the file";
PasswordBox.Password = pwd;

So when the application is open for the first time and there would not be any password in the file it would show the empty PasswordBox. And again when the password has already been set by the user the Password will be found in the file and it would get loaded in the PasswordBox.

因此,当应用程序第一次打开并且文件中没有任何密码时,它会显示空的 PasswordBox。再次,当用户已经设置了密码时,密码将在文件中找到,它会被加载到密码框中。

回答by daniel

You can have this behavior for PasswordBox to enable binding in MVVM.

您可以为 PasswordBox 设置此行为以启用 MVVM 中的绑定。

PasswordBoxBehavior.cs

密码框行为.cs

public class PasswordBoxBehavior : Behavior<PasswordBox>
{
    public bool ResetPassword
    {
        get { return (bool)GetValue(ResetPasswordProperty); }
        set { SetValue(ResetPasswordProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ResetPassword.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ResetPasswordProperty =
        DependencyProperty.Register("ResetPassword", typeof(bool), typeof(PasswordBoxBehavior), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnResetPasswordChanged));

    static void OnResetPasswordChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        PasswordBoxBehavior behavior = depObj as PasswordBoxBehavior;
        PasswordBox item = behavior.AssociatedObject as PasswordBox;
        if (item == null)
            return;

        if ((bool)e.NewValue)
            item.Password = string.Empty;

        behavior.ResetPassword = false;
    }

    private bool isRoutedEventHandlerAssign;
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(PasswordBoxBehavior), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextChanged));

    static void OnTextChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        PasswordBoxBehavior behavior = depObj as PasswordBoxBehavior;
        PasswordBox item = behavior.AssociatedObject as PasswordBox;
        if (item == null)
            return;

        if (item.Password != e.NewValue as string)
        {
            item.Password = e.NewValue as string;
        }

        if (!behavior.isRoutedEventHandlerAssign)
        {
            item.PasswordChanged += (sender, eArg) =>
            {
                behavior.Text = item.Password;
            };
            behavior.isRoutedEventHandlerAssign = true;
        }
    }

    public PasswordBoxBehavior()
    {
    }
}

Use

<PasswordBox>
    <i:Interaction.Behaviors>
        <bh:PasswordBoxBehavior 
            Text="{Binding UserPassword}"
            ResetPassword="{Binding IsResetPassword}" />
    </i:Interaction.Behaviors>
</PasswordBox>

where

在哪里

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:bh="clr-namespace:<some namespace>;assembly=<some assembly>"