Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 带MVVM的密码箱_Wpf_Mvvm_Passwordbox - Fatal编程技术网

Wpf 带MVVM的密码箱

Wpf 带MVVM的密码箱,wpf,mvvm,passwordbox,Wpf,Mvvm,Passwordbox,大家好。我正在使用MVVM,我有ViewModel使用属性密码调用UserViewModel。在视图中有一个控制密码框 <PasswordBox x:Name="txtPassword" Password="{Binding Password}" /> 但是这个xaml不起作用。你是怎么装订的??请帮帮我 出于安全原因,Password属性不是依赖属性,因此无法绑定到它。不幸的是,您需要以老式的方式在代码中执行绑定(注册OnPropertyChanged事件并通过代码更新值…)

大家好。我正在使用MVVM,我有ViewModel使用属性密码调用UserViewModel。在视图中有一个控制密码框

<PasswordBox x:Name="txtPassword" Password="{Binding Password}" />


但是这个xaml不起作用。你是怎么装订的??请帮帮我

出于安全原因,Password属性不是依赖属性,因此无法绑定到它。不幸的是,您需要以老式的方式在代码中执行绑定(注册OnPropertyChanged事件并通过代码更新值…)



我通过快速搜索了解了如何编写附加属性来回避问题。但这是否值得做,实际上取决于您对代码隐藏的厌恶程度。

您始终可以编写一个控件来包装密码,并为密码属性添加一个依赖项属性

我只想使用代码隐藏,但如果必须,您可以执行以下操作:

public class BindablePasswordBox : Decorator
{
    public static readonly DependencyProperty PasswordProperty =
        DependencyProperty.Register("Password", typeof(string), typeof(BindablePasswordBox));

    public string Password
    {
        get { return (string)GetValue(PasswordProperty); }
        set { SetValue(PasswordProperty, value); }
    }

    public BindablePasswordBox()
    {
        Child = new PasswordBox();
        ((PasswordBox)Child).PasswordChanged += BindablePasswordBox_PasswordChanged;
    }

    void BindablePasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
    {
        Password = ((PasswordBox)Child).Password;
    }

}

选中密码框上的另一个线程。 最好不要在任何DP或公共财产上保留密码


BindablePasswordBox出现问题。它只在一个方向上工作,从PasswordBox到PasswordProperty。下面是它的一个修改版本,它可以在两个方向上工作。它注册PropertyChangedCallback,并在调用时更新密码箱的密码。 我希望有人觉得这很有用

public class BindablePasswordBox : Decorator
{
    public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), typeof(BindablePasswordBox), new PropertyMetadata(string.Empty, OnDependencyPropertyChanged));
    public string Password
    {
        get { return (string)GetValue(PasswordProperty); }
        set { SetValue(PasswordProperty, value); }
    }

    private static void OnDependencyPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        BindablePasswordBox p = source as BindablePasswordBox;
        if (p != null)
        {
            if (e.Property == PasswordProperty)
            {
                var pb = p.Child as PasswordBox;
                if (pb != null)
                {
                    if (pb.Password != p.Password)
                        pb.Password = p.Password;
                }
            }
        }
    }

    public BindablePasswordBox()
    {
        Child = new PasswordBox();
        ((PasswordBox)Child).PasswordChanged += BindablePasswordBox_PasswordChanged;
    }

    void BindablePasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
    {
        Password = ((PasswordBox)Child).Password;
    }
}

为了避免在内存中随时以纯文本形式提供密码,我将该值作为参数提供给命令

<Label>User Name</Label>
<TextBox Text="{Binding UserName}" />
<Label>Password</Label>
<PasswordBox Name="PasswordBox" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 16 0 0">
    <Button Margin="0 0 8 0" MinWidth="65" 
            Command="{Binding LoginAccept}" 
            CommandParameter="{Binding ElementName=PasswordBox}">
        Login
    </Button>
    <Button MinWidth="65" Command="{Binding LoginCancel}">Cancel</Button>
</StackPanel>
用户名
密码
登录
取消
然后在我的视图模型中

public DelegateCommand<object> LoginAccept { get; private set; }
public DelegateCommand<object> LoginCancel { get; private set; }

public LoginViewModel {
    LoginAccept = new DelegateCommand<object>(o => OnLogin(o), (o) => IsLoginVisible);
    LoginCancel = new DelegateCommand<object>(o => OnLoginCancel(), (o) => IsLoginVisible);
}

private void OnLogin(object o)
{
    var passwordBox = (o as System.Windows.Controls.PasswordBox);
    var password = passwordBox.SecurePassword.Copy();
    passwordBox.Clear();
    ShowLogin = false;
    var credential = new System.Net.NetworkCredential(UserName, password);
}

private void OnLoginCancel()
{
    ShowLogin = false;
}
public DelegateCommand loginacept{get;private set;}
public DelegateCommand LoginCancel{get;private set;}
公共登录视图模型{
loginacept=newdelegatecommand(o=>OnLogin(o),(o)=>IsLoginVisible);
LoginCancel=newdelegatecommand(o=>OnLoginCancel(),(o)=>IsLoginVisible);
}
私有void OnLogin(对象o)
{
var passwordBox=(o作为System.Windows.Controls.passwordBox);
var password=passwordBox.SecurePassword.Copy();
passwordBox.Clear();
ShowLogin=false;
var-credential=新系统.Net.NetworkCredential(用户名、密码);
}
私有void OnLoginCancel()
{
ShowLogin=false;
}
虽然直接从绑定提供SecurePassword是有意义的,但它似乎总是提供空值。所以这不起作用:

    <Button Margin="0 0 8 0" MinWidth="65" 
            Command="{Binding LoginAccept}" 
            CommandParameter="{Binding ElementName=PasswordBox, Path=SecurePassword}">


是否已确保将窗口的datacontext设置为视图模型。您需要发布更多代码,以便我们了解您的问题。DataContext没问题。其他属性工作正常,但是对于PasswordBox,我不能。我使用了类似的解决方案,但我发现默认情况下使用FrameworkPropertyMetadata.BindsTwoWay注册DependencyProperty很有用,这样您就不必每次都在XAML中声明它。我知道这很旧,但是如果我使用此方法,它会删除设置FontSize和ContentAlignment的功能。我该怎么做呢?我也经历过同样的事情!你知道为什么“直接来自绑定的SecurePassword”不起作用吗?除了对该特定类型有故意的限制之外,我不知道。SecurePassword不是可能导致问题的DependencyProperty,而是标准的只读属性。但是有人会认为,如果不传递整个控件,您仍然可以将其作为参数传递。在视图模型中处理控件显然违反了MVVM模式。是的,它违反了MVVM模式。框架中的bug有时需要打破模式。在这种情况下,安全性在我的行业中占了上风,最好在内存中加密密码。模式应该具有易于理解的代码,即使在更改语言和框架时也是如此。在我看来,绑定和用法都很清楚。