用于引发依赖属性RaisePropertyChanged事件的MVVM模式
本文关键字:事件 MVVM 模式 RaisePropertyChanged 属性 依赖 用于 | 更新日期: 2023-09-27 18:08:57
我有一些只读属性,它们根据视图模型中的兄弟属性返回一个值。为了将它们绑定到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")
,并使这种场景更容易管理?可以在视图模型的集中位置添加这些类型的映射。
看看这个https://github.com/steinborge/ProxyTypeHelper。它会做你的MVVM/WPF,并自动连接propertychangeevents。所以你的例子是这样的:
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()
{
}
据我所知,这种模式在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",似乎该属性可能是命令绑定的开关。如果你基于这个布尔值启用/禁用按钮,那么我建议声明一个iccommand和CanExecute。它可以更优雅,因为按钮有这个框架内置的有用和优雅的功能。