ICommand的不工作 [英] ICommand doesn't work
问题描述
我开始以 MVVM
模式,我有我的按钮的命令有问题。我有一个包含窗口的文本框
用于登录,定制 PasswordBox
使用密码的DependencyProperty
密码(我知道的任何密码不应该被保存在内存中,但它只是为了好玩,所以不要感到沮丧:))。还有一个按钮,我想,当且仅当登录名和密码都是不为空,它被启用。但是我的命令不能正常工作。下面是代码:
I am starting with MVVM
pattern and I have a problem with my button's command. I have a window which contains a TextBox
for login and a custom PasswordBox
with Password DependencyProperty
for password (I know that any password should not be kept in memory, however it is only for fun, so do not be frustrated :) ) . There is also a button and I want it to be enabled if and only if the login and password are both not empty. However my command does not work properly. Here is the code:
登录窗口XAML:
<Window x:Class="WpfMVVMApplication1.LoginWindow"
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:WpfMVVMApplication1"
xmlns:vm="clr-namespace:WpfMVVMApplication1.ViewModel"
mc:Ignorable="d"
Title="Login" WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
Width="250" Height="150">
<Window.DataContext>
<vm:LoginViewModel />
</Window.DataContext>
<Window.Resources>
<!-- here some styles for controls -->
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Login:"/>
<TextBlock Text="Password:" Grid.Row="1"/>
<TextBox Text="{Binding Login, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<local:MyPasswordBox Grid.Row="1" PasswordText="{Binding Password, Mode=TwoWay}"/>
<Button Command="{Binding SaveUserCommand}"/>
</Grid>
我的LoginViewModel类
public class LoginViewModel : INotifyPropertyChanged
{
public LoginViewModel()
{
SaveUserCommand = new Command(x => SaveUser(), x => { return !string.IsNullOrEmpty(Login) && !string.IsNullOrEmpty(Password); });
}
public event PropertyChangedEventHandler PropertyChanged;
public ICommand SaveUserCommand { get; private set; }
private string login;
private string password;
public string Login
{
get
{
return login;
}
set
{
login = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Login"));
}
}
public string Password
{
get
{
return password;
}
set
{
password = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Password"));
}
}
public void SaveUser() { }
}
此外 MyPasswordBox
类可能是有用的:
<UserControl x:Class="WpfMVVMApplication1.MyPasswordBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfMVVMApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<PasswordBox x:Name="password" PasswordChanged="password_PasswordChanged"/>
</Grid>
public partial class MyPasswordBox : UserControl
{
public MyPasswordBox()
{
InitializeComponent();
PasswordText = "";
}
public static readonly DependencyProperty PasswordTextProperty =
DependencyProperty.Register("PasswordText", typeof(string), typeof(MyPasswordBox), new FrameworkPropertyMetadata(""));
public string PasswordText
{
get { return (string)GetValue(PasswordTextProperty); }
set { SetValue(PasswordTextProperty, value); }
}
private void password_PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordText = password.Password;
}
}
我写了一些的单元测试,检查结果SaveUserCommand CanExecute方法和他们的全部通过。此外,我跑在Visual Studio 调试将在登录的制定者断点和
密码
属性和他们都设置正确
I wrote some unit tests for that which checks the result of SaveUserCommand CanExecute method and they all passed. Furthermore, I run the debug in Visual Studio adding breakpoints in setters of Login
and Password
properties and they both are set properly.
我已经江郎才尽了什么,我会做出错误的。任何人可以帮助我吗?
I have run out of ideas what I could make wrong. Can anybody help me?
我觉得我不会通知更改正确的命令,但是我不知道该怎么做。
I feel that I don't notify the command about the changes properly, however I do not know how to do that
推荐答案
为了为WPF来改变拿起是否可以执行的命令,该命令的 CanExecuteChanged
事件需要被解雇。
In order for WPF to pick up a change to whether a command can be executed, the command's CanExecuteChanged
event needs to be fired.
您需要触发该事件时的登录或更改密码。您还没有表现出你的类命令
的来源,但它需要有触发一个方法的 CanExecuteChanged
事件。然后,只需调用从登录
和密码
属性设置器。
You will need to fire this event when the login or the password changes. You haven't shown the source of your class Command
, but it will need to have a method that fires its CanExecuteChanged
event. Then, just call this method from the Login
and Password
property setters.
这篇关于ICommand的不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!