无法从 ViewModel 绑定到模型的成员

Can't bind to a member of a Model from a ViewModel

MyProduct 是具有可以更改的 HasError 布尔值 属性(带有 OnPropertyChanged ...)的模型。 MyProductDialogViewModel 是:

class ProductDialogViewModel : Notifier
{
    public ProductDialogViewModel() { }        
    public MyProduct Product { get; set; }               
    public bool HasError
    {
        get { return Product.HasError; }
    }
}

我已将 MyProductDialogViewModel 实例分配给 BaseContentControl.DataContext 以扩充 ContentControl。 可以使用模板绑定使用具有 HasError 属性 的不同 ViewModel 来扩充此视图。

<ContentControl x:Name="BaseContentControl" Content="{Binding}" ... >

然后我尝试直接从它的 DataContext 中提取信息。 这不起作用:

<Label Content="{Binding ElementName=BaseContentControl, Path=DataContext.HasError}"/>

但这很完美。

<Label Content="{Binding ElementName=BaseContentControl, Path=DataContext.Product.HasError}"/>

我认为这可能是 ViewModel 中的通知问题,所以我更改为:

class ProductDialogViewModel : Notifier
{
    public ProductDialogViewModel() { }

    public MyProduct Product { get; set; }        

    public bool HasError
    {
        get { return Product.HasError; }
        set
        {
            if (Product.HasError != value)
            {
                Product.HasError = value;
                OnPropertyChanged("HasError");
            }
        }
    }
}

但无济于事(实际上 set 方法从未被调用,因此它永远不会通知)。

我不想直接引用特定的 Model 实例,因为 View 可以用不同的 ViewModel 扩充。 我该怎么办?

谢谢

您必须传播 MyProductPropertyChanged 事件,即订阅它并调用 OnPropertyChanged(nameof(HasError)) if HasError 属性 of MyProduct ] 正在更改:

public class ProductDialogViewModel : Notifier
{
    public ProductDialogViewModel() { }

    private MyProduct _product = null;
    public MyProduct Product
    {
        get { return _product; }
        set
        {
            if (_product!=null)
            {
                _product.PropertyChanged -= Product_PropertyChanged;
            }
            _product = value;
            if (_product != null)
            {
                _product.PropertyChanged += Product_PropertyChanged;
            }
        }
    }

    private void Product_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName==nameof(MyProduct.HasError))
        {
            OnPropertyChanged(nameof(HasError));
        }
    }

    public bool HasError => Product.HasError;
}