Caliburn.Micro 可以操作语法和行为

Caliburn.Micro can action syntax and behaviour

Caliburn.Micro 可以调用带有参数的动作绑定,但不能没有参数。我是 Caliburn.Micro 的新手。有人可以解释这种行为吗?我已经完成了 http://caliburnmicro.com/documentation/introduction.

以下Xaml

<TextBox x:Name="YourName" />
<TextBox x:Name="Address" />
<Button x:Name="Save" />

这是有效的:

public void Save(string yourName, string address)
{
    MessageBox.Show( $"Your Name : {yourName}{Environment.NewLine}Address : {address}", "You have entered:", MessageBoxButton.OK);
}

public bool CanSave(string yourName, string address) => (!string.IsNullOrWhiteSpace(yourName) && !string.IsNullOrWhiteSpace(address));

这不起作用

public void Save()
    {
        MessageBox.Show( $"Your Name : {yourName}{Environment.NewLine}Address : {address}", "You have entered:", MessageBoxButton.OK);
    }

public bool CanSave() => (!string.IsNullOrWhiteSpace(yourName) && !string.IsNullOrWhiteSpace(address));

TL;DR:只需使用 Can-属性 而不是 Can 方法,并在前提条件之一可能发生变化时引发 PropertyChanged 事件。

有两种方法在Caliburn.Micro中实现Action Guards:

When a handler is found for the “SayHello” message, it will check to see if that class also has either a property or a method named “CanSayHello.” If you have a guard property and your class implements INotifyPropertyChanged, then the framework will observe changes in that property and re-evaluate the guard accordingly.


All About Actions - Caliburn.Micro Documentation

使用方法作为守卫

这是您尝试过的。它非常适用于具有参数的 Action 方法,因为每次这些参数之一发生变化时,守卫都会重新评估。工作中没有魔法 - 实际上,它只是在幕后使用 WPF 数据绑定将 Action 实例绑定到参数值。一旦绑定引擎检测到更改,就会调用 guard 方法。这就是为什么在没有参数的情况下它不会起作用的原因,并且没有办法自己轻松触发守卫。

使用属性作为守卫

这是您应该在您的案例中使用的内容:添加一个 Get-only 属性,就像这样:

public bool CanSave => (!string.IsNullOrWhiteSpace(yourName) 
                        && !string.IsNullOrWhiteSpace(address));

然后,每当 yournameaddress 发生变化时,只需调用:

this.NotifyOfPropertyChange(nameof(CanSave));

这样,框架就会知道 Guard 的值可能已经改变并重新评估它。

如果你想调用带有参数的方法,你应该这样做:

<Button cal:Message.Attach="[Event Click] = [Action Save(YourName.Name, Address.Name)]"/>

而不是 enable/disable 保存按钮,你应该有 属性 YourName, Address and CanSave...并且每次其他更改时更新 属性 (CanSave) (YouName , 地址).

NotifyOfPropertyChange(nameof(CanSave));

希望对您有所帮助