我注意到我的 .NET MAUI 应用程序中有关将 NotifyCanExecuteChangedFor 与 ObservableCollection 结合使用的奇怪行为。
这是前提: 我的用户界面如下:
对于这个问题来说,最重要的是右上角的按钮,上面写着“标准”、“多个”和“条目”,下方的按钮位于左上角的“添加答案”和右上角的“删除最后一个答案”。
如果单击“添加答案”按钮,则会将附加答案添加到下方灰色框中的 CollectionView 中:
现在,UI中的CollectionView绑定到对应ViewModel中的ObservableCollection,如下所示:
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(AddAnswerCommand))]
[NotifyCanExecuteChangedFor(nameof(RemoveLastAnswerCommand))]
private ObservableCollection<Answer> _answers = new();
对应的功能如下:
[RelayCommand(CanExecute = nameof(CanAddAnswer))]
private void OnAddAnswer()
{
AddEmptyAnswerToAnswers();
}
[RelayCommand(CanExecute = nameof(CanRemoveLastAnswer))]
private void OnRemoveLastAnswer()
{
var lastIndex = Answers.Count-1;
Answers.RemoveAt(lastIndex);
}
private bool CanAddAnswer()
{
return Answers.Count < 6;
}
private bool CanRemoveLastAnswer()
{
return Answers.Count > 1;
}
奇怪的行为是一方面,“删除最后一个答案”按钮没有收到更改通知。
另一方面,当按下“标准”、“多个”或“输入”按钮时,“删除最后一个答案”按钮似乎会相应更新:
上面的三个按钮本质上是绑定到“QuestionType”字段的,如下:
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(AddAnswerCommand))]
[NotifyCanExecuteChangedFor(nameof(RemoveLastAnswerCommand))]
[NotifyCanExecuteChangedFor(nameof(SwitchToStandardCommand))]
[NotifyCanExecuteChangedFor(nameof(SwitchToMultipleCommand))]
[NotifyCanExecuteChangedFor(nameof(SwitchToEntryCommand))]
private int _questionType = 0;
//...
[RelayCommand(CanExecute = nameof(CanSwitchToStandard))]
private void OnSwitchToStandard()
{
QuestionType = 0;
}
[RelayCommand(CanExecute = nameof(CanSwitchToMultiple))]
private void OnSwitchToMultiple()
{
QuestionType = 1;
}
[RelayCommand(CanExecute = nameof(CanSwitchToEntry))]
private void OnSwitchToEntry()
{
QuestionType = 2;
}
private bool CanSwitchToStandard()
{
return QuestionType != 0;
}
private bool CanSwitchToMultiple()
{
return QuestionType != 1;
}
private bool CanSwitchToEntry()
{
return QuestionType != 2;
}
我现在的问题是,为什么它会起作用?为什么“删除最后一个答案”按钮没有收到 ObservableCollection 中的更改通知,但一旦使用上面的按钮之一,就会正确传递通过“QuestionType”属性的通知?
我尝试更改并重新排列 [NotifyCanExecuteChangedFor] 注释。但是,我也很难找到专门针对这些注释的文档。
感谢@Jason,我找到了一个简单的答案:
在类构造函数中添加事件处理程序解决了问题:
Answers.CollectionChanged += (sender, e) =>
{
AddAnswerCommand.NotifyCanExecuteChanged();
RemoveLastAnswerCommand.NotifyCanExecuteChanged();
};