【问题标题】:ICommand doesn't workICommand 不起作用
【发布时间】:2015-08-29 09:54:46
【问题描述】:

我从MVVM 模式开始,我的按钮命令有问题。我有一个窗口,其中包含一个用于登录的TextBox 和一个带有密码DependencyProperty 的自定义PasswordBox 用于密码(我知道任何密码都不应该保存在内存中,但这只是为了好玩,所以不要沮丧:) ) 。还有一个按钮,当且仅当登录名和密码都不为空时,我希望启用它。但是我的命令无法正常工作。代码如下:

LoginWindow 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 中运行调试,在 LoginPassword 属性的设置器中添加断点,并且它们都设置正确。

我已经想不出我会做错什么了。有人可以帮帮我吗?

我觉得我没有正确通知命令有关更改,但是我不知道该怎么做

【问题讨论】:

    标签: c# wpf xaml mvvm icommand


    【解决方案1】:

    为了让 WPF 识别是否可以执行命令的更改,需要触发命令的 CanExecuteChanged 事件。

    当登录名或密码更改时,您需要触发此事件。您还没有显示您的类Command 的源代码,但它需要有一个触发其CanExecuteChanged 事件的方法。然后,只需从LoginPassword 属性设置器调用此方法即可。

    【讨论】:

      猜你喜欢
      • 2018-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2013-08-01
      • 2017-06-10
      • 2010-11-30
      相关资源
      最近更新 更多