用于引发依赖属性RaisePropertyChanged事件的MVVM模式

时间:2014-06-16 23:02:00

标签: c# wpf design-patterns mvvm mvvm-light

我有一些只读属性,它们根据视图模型中的兄弟属性返回一个值。为了将它们绑定到XAML,我需要向兄弟属性添加额外的RaisePropertyChanged事件。这感觉有点不雅。

简化示例:

public bool IsPurchased
{
    get
    {
        return _IsPurchased;
    }
    set
    {
        if (_IsPurchased == value) return;
        _IsPurchased = value;
        RaisePropertyChanged("IsPurchased");
        RaisePropertyChanged("IsAvailableToUse");
    }
}
private bool _IsPurchased = false;

public bool IsDownloaded
{
    get
    {
        return _IsDownloaded;
    }
    set
    {
        if (_IsDownloaded == value) return;
        _IsDownloaded = value;
        RaisePropertyChanged("IsDownloaded");
        RaisePropertyChanged("IsAvailableToUse");
    }
}
private bool _IsDownloaded = false;

public bool IsAvailableToUse
{
    get
    {
        return IsPurchased && IsDownloaded;
    }
}

有没有人有一个很好的模式可以消除贡献属性中的额外RaisePropertyChanged("IsAvailableToUse")并使这些场景更容易管理?也许在视图模型中的集中位置添加这些类型的映射。

2 个答案:

答案 0 :(得分:1)

据我所知,模式在MVVM中相当常见。如果要将所有属性组合在一起,可以覆盖RaisePropertyChanged的实现,以便按以下方式处理分组的案例。

   protected override void RaisePropertyChanged(string propertyName = null)
    {
        PropertyChangedEventHandler handler = this.PropertyChangedHandler;
        switch (propertyName)
        {
            case "IsDownloaded":
            case "IsAvailableToUse":
            case "IsPurchased":
                if (handler != null) handler(this, new PropertyChangedEventArgs("IsDownloaded"));
                if (handler != null) handler(this, new PropertyChangedEventArgs("IsAvailableToUse"));
                if (handler != null) handler(this, new PropertyChangedEventArgs("IsPurchased"));

                break;
            default:
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
                break;
        }
    }

在一个不相关的说明中,我注意到你的一个属性名为" IsAvailableToUse"并且看起来该属性可能是命令绑定的开关。如果您根据此布尔值启用/禁用按钮,那么我建议声明ICommand和CanExecute。它可以更优雅,因为按钮具有框架内置的这种有用和优雅的功能。

答案 1 :(得分:1)

看看这个https://github.com/steinborge/ProxyTypeHelper。它会做你的MVVM / WPF并自动连接propertychangedevents。所以你的例子是这样的:

    public bool IsDownloaded {get;set;}
    public bool IsPurchased { get; set; }

    [LinkToProperty("IsDownloaded")]
    [LinkToProperty("IsPurchased")]
    public bool IsAvailableToUse
    {
        get
        {
            return IsPurchased && IsDownloaded;
        }
    }

    [LinkToCommand("PurchaseCommand")]
    private void btnPurchase()
    {
    }

    [LinkToCommand("DownloadCommand")]
    private void btnDownload()
    {
    }