Caliburn Micro的Guard方法在属性更改时未进行评估

18

我一直在使用Caliburn Micro MVVM框架,但是在保护方法方面遇到了一些问题。

我有一个视图模型:

public class MyViewModel : PropertyChangedBase, IMyViewModel
一个属性:
public DateTime? Date
{
   get{return this.date; }
   set
   {
      this.date = value;
      this.NotifyOfPropertyChange(() => Date);
   }
}

此外,我的视图模型中有一个带有守卫方法的方法

public void Calculate()
{
    // ..some code..
}

public bool CanCalculate()
{
    return this.Date.HasValue;
}

还有一个按钮在我的视图中:

我遇到的问题是,当加载时 CanCalculate 方法被执行,但当我输入文本字段的值时,它不会重新评估 CanCalculate 方法。我在设置数据绑定视图模型属性时触发了属性更改事件,那么问题可能是什么?


你能展示一下视图的代码,同时也展示一下在你的视图模型中调用NotifyOfPropertyChanged方法的位置吗? - devdigital
3个回答

34

好的,我明白了。我没有意识到必须触发守卫方法通知,认为框架会自动处理,但这很有道理。

所以我把我的属性设置器改成了:

public DateTime? Date
{
   get
   {
      return this.date; 
   }
   set
   {
      this.date = value;
      this.NotifyOfPropertyChange(() => Date);
      this.NotifyOfPropertyChange(() => CanCalculate);
   }
}

并将我的CanCalculate方法更改为属性:

public bool CanCalculate
{
    get
    {
        return this.Date.HasValue;
    }
}

现在一切都正常工作了 :)


3
将其转换为一个具有getter的布尔属性。 - Eduardo Brites
对于任何试图使它适用于带参数的保护方法的人:如果参数对象包含在另一个属性中(例如,集合绑定到列表框并且保护是每个项目),则可以仅为(看似)不相关的属性通知属性更改。 - Jony Adamit

2

如果你不需要CanExecute是方法,因为你不会使用参数。那么你可以将其重写为具有标准通知和仅getter的属性。并且在你假定getter的结果已更改时调用它的PropertyChanged。


0

我假设这些是通过Command调用的(在调用这些方法周围的一些代码会有所帮助)。

如果你想让命令基于某些输入重新评估,则需要调用CommandManager.InvalidateRequerySuggested(),以便调用命令CanExecutes。 由于命令绑定到按钮而不是文本框,因此它不会更新。 在属性设置器(绑定到文本框的设置器)中,您必须告诉框架重新查询命令。 这反过来将调用您的CanCalculate方法。

如果Calculate和CanCalculate方法与命令无关,则上述内容将无法帮助。


Caliburn Micro 似乎忽略了 CommandManager.InvalidateRequerySuggested(),这实际上是一个小疏忽。 :/ - Meirion Hughes
3
这并非疏忽。Caliburn.Micro根本不使用Commands,而是使用Actions/ActionMessages - mnn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接