满足条件时,CanExecute()不启用按钮

时间:2014-09-13 23:03:03

标签: c# wpf relaycommand

我的应用程序非常简单,TextBoxButton。当输入TextBox的文本长度超过5个字符时,将启用该按钮。这是我的ViewModel的代码:

private string _text { get; set; }
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");
    }
}

private ICommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}

private bool ButtonCommandCanExecute()
{
    if (this.Text.Length < 5)
    {
        return false;
    }
    else
    {
        return true;
    }
}

private void ButtonCommandExecute()
{
    this.Text = "Text changed";
}

public MainWindowViewModel()
{
    //
}

使用此XAML绑定TextBoxButton

<Button Content="Button" HorizontalAlignment="Left" 
                Margin="185,132,0,0" VerticalAlignment="Top" Width="120"
                Command="{Binding Path=ButtonCommand}" />

<TextBox HorizontalAlignment="Left" Height="23" 
         Margin="185,109,0,0" TextWrapping="Wrap" 
         Text="{Binding Path=Text, Mode=TwoWay}" VerticalAlignment="Top" Width="120"/>

DataContext似乎设置正确,但这只是因为我是WPF初学者:

private MainWindowViewModel view_model;

public MainWindow()
{
    InitializeComponent();

    view_model = new MainWindowViewModel();

    this.DataContext = view_model;
}

当我输入TextBox时,Button永远不会启用。

3 个答案:

答案 0 :(得分:14)

ICommand接口的某些实现具有通知“CanExecute”是否已更改的特殊方法。 RelayCommand类(MVVM Light)有这样的方法。

private string _text;
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");

        // There is a special RelayCommand method to notify "CanExecute" changed.
        // After this call, the "CanExecute" state is "re-evaluated" automatically by binding using CanExecute Func passed into RelayCommand constructor.
        _buttonCommand.RaiseCanExecuteChanged();
    }
}

private RelayCommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}

这个问题很有用:What is CanExecuteChanged for?

答案 1 :(得分:1)

实际上你必须让Bool Property绑定到Button Control的IsEnabled属性。当Textbox中的文本超过五个字符时,将此属性设置为true - 您必须在Setter of Text属性中执行此操作因为这是在TextBox中键入时调用的内容。

基本关于命令: - 这些基本上是将例如Clicks事件报告给C#代码,例如Viewmodel / Page.cs。这样你就可以执行一些任务了。它与启用和禁用按钮无关。

遵守守则: -

private string _text { get; set; }
public string Text
{
    get { return _text; }
    set
    {
        _text = value;

        if(_text.Length  > 5)
        // Enable button here
        // and command does not enable Buttons they are basically report the clicks events.
        IsButtonEnabled = true;

        OnPropertyChanged("Text");
    }
}

启用按钮创建Bool类型属性,调用IsButtonEnabled并将此属性绑定到Xaml中的Button。

private bool _IsButtonEnabled { get; set; }
public bool IsButtonEnabled
{
    get { return _IsButtonEnabled ; }
    set
    {
        _IsButtonEnabled = value;
        OnPropertyChanged("IsButtonEnabled");
    }
}

在Xaml中: -

<Button Content="Button" HorizontalAlignment="Left" 

             IsEnabled="{Binding IsButtonEnabled}"

            Margin="185,132,0,0" VerticalAlignment="Top" Width="120"
            Command="{Binding Path=ButtonCommand}" />

答案 2 :(得分:-2)

尝试对代码进行少许修改并告诉我它是否有效:

private string _text { get; set; }
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");
        ButtonCommandCanExecute();
    }
}

private ICommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}

private bool ButtonCommandCanExecute()
{
    if (this.Text.Length < 5)
    {
        return false;
    }
    else
    {
        return true;
    }
}

private void ButtonCommandExecute()
{
    this.Text = "Text changed";
}

public MainWindowViewModel()
{
    //
}