【问题标题】:Caliburn.Micro, MVVM pattern: CanExecute command doesn't workCaliburn.Micro,MVVM 模式:CanExecute 命令不起作用
【发布时间】:2016-12-10 22:55:47
【问题描述】:

这是我的观点:

<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
    <Label>Customer name:</Label>
    <TextBox Text="{Binding Customer.Name, UpdateSourceTrigger=PropertyChanged}" Width="136"/>
    <Button x:Name="UpdateClick">Update</Button>
</StackPanel>

这是我的视图模型:

private Customer customer;
public Customer Customer
{
    get { return customer; }
    set { customer = value; NotifyOfPropertyChange(() => Customer); }
}

public bool CanUpdateClick 
{ 
    get 
    {
        if (string.IsNullOrEmpty(customer.Name))
        {
            return false;
        }
        return true; 
    } 
}

public void UpdateClick()
{
    //...
}

这是我的模型:

private string name;
public string Name
{
    get { return name; }
    set { name = value; NotifyOfPropertyChange(() => Name); }
}

所以我有 UpdateClick 方法,它工作得很好。我也有 CanUpdateClick 属性,但它不起作用,我不知道为什么?当文本框为空时,应禁用 UI 上的按钮。请帮忙!

【问题讨论】:

  • 那是因为 notify 属性改变只是通知Customer.Name 改变了而不是CanUpdateClick。 Name 是客户类中的一个属性,因此必须利用客户的 propertychanged 才能获得该通知。

标签: c# wpf mvvm caliburn.micro


【解决方案1】:

您可以订阅Customer 类的PropertyChanged 事件(因为您似乎是PropertyChangedBase 的子类)并在Name 属性更改时调用NotifyOfPropertyChanged(() =&gt; CanUpdateClick)

// in your view model
// i'm assuming here that Customer is set before your view model is activated
protected override void OnActivate()
{
    base.OnActivate();
    Customer.PropertyChanged += CustomerPropertyChangedHandler;
}

protected override void OnDeactivate(bool close)
{
    base.OnDeactivate(close);
    // unregister handler
    Customer.PropertyChanged -= CustomerPropertyChangedHandler;
}

// event handler
protected void CustomerPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(Customer.Name))
    {
        NotifyOfPropertyChange(() => CanUpdateClick);
    }
}

或者,您可以在视图模型中创建NameCustomerName 属性以绑定到a) 使用Customer.Name 作为支持字段或b) 使用普通支持字段然后设置Customer.Name更新时:

在你看来:

<TextBox Text="{Binding CustomerName, UpdateSourceTrigger=PropertyChanged}" Width="136"/>

以下是在视图模型中实现选项 a 的方法:

public string CustomerName
{
    get { return Customer.Name; }
    set
    {
        Customer.Name = value;
        NotifyOfPropertyChange(); // CallerMemberName goodness
        NotifyOfPropertyChange(() => CanUpdateClick);
    }
}

【讨论】:

  • 谢谢。我更喜欢你的第二个建议。但是后来我不知道如何在显示验证消息的 View 中实现 ContentPresenter?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
相关资源
最近更新 更多