MVVM Light - 对RelayCommand使用RaiseCanExecuteChanged

时间:2014-06-14 16:23:15

标签: c# wpf mvvm binding canexecute

我正在使用MVVM模式。我的观点,我有人员详细信息的文本框,其中一个是idBox。此外,视图包含几个按钮,其中一个是editModeBtn。

我希望只有在idBox中有一个有效的int时才能启用editModeBtn。

editBtn的我的Xaml(在视图中)如下所示:

<Button x:Name="editModeBtn" Content="Edit" Command="{Binding ChangeToEditScreenCommand}"  CommandParameter="{Binding ElementName=idBox, Path=Text}"></Button>

在相应的viewModel中,我有以下代码:

private RelayCommand<string> _changeToEditScreenCommand;

    public RelayCommand<string> ChangeToEditScreenCommand
    {
        get
        {
            if (_changeToEditScreenCommand == null)
            {
                _changeToEditScreenCommand = new RelayCommand<string>((param) => ChangeToEditScreen(), (param) => CanEdit(param));
            }

            return _changeToEditScreenCommand;
        }
    }

另外,在CanExecute方法(我的情况下是CanEdit)中,我想检查参数(id)是否设置为有效的int然后返回true。错,否则。

private bool CanEdit(string currentInsertedId)
    {
        int idValue;
        bool result = Int32.TryParse(currentInsertedId, out idValue);
        if (result)
        {
            if (idValue > 0) { return true; };
            return false;
        }
        return false;
    }

基本上,我希望每次从idBox写入或删除某些内容时都会调用该命令的canExecute方法。我应该在哪里放置命令的RaiseCanExecuteChanged()?如果我没有使用MVVM,我可以把它放在textBox textChanged事件中,但这不是这里的情况。从未使用过RaiseCanExecuteChanged,所以只想确保。谢谢!

1 个答案:

答案 0 :(得分:3)

你为什么要走CommandParameter路?您是否只需使用TextBox.TextUpdateSourceTrigger=PropertyChanged属性绑定到VM即可。一旦TextBox中的文本发生变化,这应该得到VM中Text的绑定属性,而不是TextBox失去焦点时的默认值。

在您的情况下,这是您似乎想要的行为。因此,您需要的只是RelayCommand用于您的命令,而不是带有参数的RelayCommand<T>

所以说简单的xaml显示上述方法:

<TextBox Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding ButtonCommand}"
        Content="My Button" />

并在VM中:

public string Title {
  get {
    return _title;
  }

  set {
    if (_title == value) {
      return;
    }

    _title = value;
    RaisePropertyChanged(() => Title);
  }
}

public RelayCommand ButtonCommand { get; private set; }

private bool CanEdit(string title) {
  int idValue;
  bool result = Int32.TryParse(title, out idValue);
  if (!result) {
    return false;
  }

  return idValue > 0;
}

ctor() {
  ButtonCommand = new RelayCommand(() => Debug.WriteLine("Called"), () => CanEdit(Title));
}

这本身就可以实现您的查询。但是对于你的问题abt RaiseCanExecuteChanged()的使用,在这个例子中,Title的属性设置器类似于相关TextBox的textChanged事件处理程序(我说这只是cos,现在每次调用setter文本框中的文字更改)

因此,为了绝对保证在文本更改时调用CanExecute(),您可以从ButtonCommand.RaiseCanExecuteChanged()属性设置器中调用Title,在其中引发它的PropertyChanged事件。