c# - MVVM Light - RaiseCanExecuteChanged 用于 RelayCommand

标签 c# wpf mvvm binding canexecute

我正在使用 MVVM 模式。我是我的观点,我有个人详细信息的文本框,其中之一是 idBox。此外,该 View 由几个按钮组成,其中之一是 editModeBtn。

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

我的 editBtn 的 Xaml(在 View 内)如下所示:

<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,所以只想确保。谢谢!

最佳答案

你为什么要走通过 CommandParameter 的路线? ?你不能只绑定(bind)你的TextBox.Text吗?属性为 UpdateSourceTrigger=PropertyChanged 的 VM .这应该会在 TextBox 中的文本更改后立即更新 VM 中 Text 的绑定(bind)属性,而不是 TextBox 失去焦点时的默认值。

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

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

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

在虚拟机中:
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));
}

这本身就可以实现您的查询。但是,对于您的问题,使用 RaiseCanExecuteChanged() , 在本例中,Title 的属性 setter 有点类似于关联 TextBox 的 textChanged 事件处理程序(我说这只是因为现在每次文本框中的文本更改时都会调用 setter)

所以绝对保证您的CanExecute()文本变化时调用,可以调用ButtonCommand.RaiseCanExecuteChanged()来自 Title引发它的 PropertyChanged 事件的属性 setter 。

关于c# - MVVM Light - RaiseCanExecuteChanged 用于 RelayCommand,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24221924/

相关文章:

WPF:文本框和绑定(bind)到 Double 无法键入。在上面

c# - 如何获取 WPF DataGrid 单元格的位置?

c# - 'Data Structure' 和 'compiled code' 有什么区别

c# - 如何从两个 List<string> 中获取不同的值?

c# - 如何在 WriteJson 期间删除属性

wpf - 当 DataGrid 接收到键盘焦点时,关注 SelectedItem 的 DataGridCell

wpf - 如何在控件内引用用户控件主机的 StaticResource?

wpf - 带导航的ICommand

xamarin - 在不使用现有MVVM框架的情况下使用MVVM模式进行页面导航

c# - Activator.CreateInstance 在这种情况下的优势