简体   繁体   English

MVVM Light-将RaiseCanExecuteChanged用于RelayCommand

[英]MVVM Light - usage of RaiseCanExecuteChanged for RelayCommand

I'm using MVVM Pattern. 我正在使用MVVM模式。 Im my View, I have textboxes for Person details, which one of them is idBox. 在我看来,我有用于“个人”详细信息的文本框,其中之一是idBox。 Also, the view consists of several buttons, which one of them is editModeBtn. 此外,该视图由几个按钮组成,其中之一是editModeBtn。

I want the editModeBtn to be enabled only when there is a valid int inside the idBox. 我希望仅在idBox中有有效的int时才启用editModeBtn。

My Xaml (within view) for the editBtn looks like the following: 我的editBtn Xaml(在视图中)如下所示:

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

In the corresponding viewModel, I have the following code: 在相应的viewModel中,我有以下代码:

private RelayCommand<string> _changeToEditScreenCommand;

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

            return _changeToEditScreenCommand;
        }
    }

Also, in the CanExecute method (CanEdit in my case), I want to check if the parameter (id) is set to a valid int and then return true. 另外,在CanExecute方法(在我的情况下为CanEdit)中,我想检查参数(id)是否设置为有效的int,然后返回true。 False, otherwise. 错误,否则。

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;
    }

Basically, I want the canExecute method of the command to be invoked everytime something is written or removed from the idBox. 基本上,我希望每次在idBox中写入或删除某些内容时都调用该命令的canExecute方法。 Where should I put the RaiseCanExecuteChanged() of the command? 我应该将命令的RaiseCanExecuteChanged()放在哪里? If I haven't used MVVM, I could put it in the textBox textChanged event, but this is not the case here. 如果我没有使用过MVVM,则可以将其放在textBox textChanged事件中,但实际情况并非如此。 Never used the RaiseCanExecuteChanged, so just want to ensure. 从未使用过RaiseCanExecuteChanged,因此只想确保即可。 Thanks! 谢谢!

Why are you going down the route of passing a CommandParameter ? 为什么要沿着传递CommandParameter的路走下去? Can't you just bind your TextBox.Text property to the VM with a UpdateSourceTrigger=PropertyChanged . 您不能仅使用UpdateSourceTrigger=PropertyChangedTextBox.Text属性绑定到VM。 This should get the bound property for Text in the VM get updated as soon as text in the TextBox changes, instead of the default which would be when the TextBox looses focus. 一旦TextBox中的文本更改,这应该获取VM中Text的bound属性更新,而不是TextBox失去焦点时的默认属性。

In your case this is the Behavior you seem to want. 在您的情况下,这就是您似乎想要的行为。 So with that all you need is a RelayCommand for your Command and not a RelayCommand<T> with a parameter. 因此,与所有你需要的是一个RelayCommand为您的命令,而不是一个RelayCommand<T>有一个参数。

So say simple xaml showing the above approach: 所以说简单的xaml显示上述方法:

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

and in the VM: 并在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));
}

This by itself would achieve your query. 这本身将实现您的查询。 However for your question abt usage of RaiseCanExecuteChanged() , In this example the property setter of Title is kind of similar to the textChanged event handler of the associated TextBox(I say this just cos that setter is now invoked everytime the text in the textbox changes) 但是对于您使用RaiseCanExecuteChanged() ,在本示例中, Title的属性设置器与关联的TextBox的textChanged事件处理程序有点相似(我说这是因为设置器现在每次在文本框中更改文本时都会被调用)

So to absolutely guarantee your CanExecute() is invoked when the text changes, you can call ButtonCommand.RaiseCanExecuteChanged() from the Title property setter where you raise it's PropertyChanged event. 因此,要完全保证在文本更改时可以调用CanExecute() ,可以从Title属性设置器中调用ButtonCommand.RaiseCanExecuteChanged() ,在该属性引发它的PropertyChanged事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM