C# 在WPF兼容属性中包装属性以实现INotifyPropertyChanged

C# 在WPF兼容属性中包装属性以实现INotifyPropertyChanged,c#,wpf,mvvm,inotifypropertychanged,C#,Wpf,Mvvm,Inotifypropertychanged,在我的WPF应用程序中,我的模型类继承自一个类父类: 模型:父类,INotifyPropertyChanged 我的应用程序只是为了提供一个UI来测试和验证父类。因此模型实际上只不过是一个INotifyPropertyChanged实现,它覆盖了ParentClass 但是,我仍然需要从父类访问数据,并使其响应UI 假设切片是父类中的一个属性,而WPFSlicing是模型中的一个属性,我目前就是这样做的。我正在将每个父属性包装到WPF兼容的属性中 public Thickness WPFSlic

在我的WPF应用程序中,我的
模型
类继承自一个类
父类

模型:父类,INotifyPropertyChanged

我的应用程序只是为了提供一个UI来测试和验证父类。因此
模型
实际上只不过是一个
INotifyPropertyChanged
实现,它覆盖了
ParentClass

但是,我仍然需要从父类访问数据,并使其响应UI

假设
切片
父类
中的一个属性,而
WPFSlicing
模型
中的一个属性,我目前就是这样做的。我正在将每个父属性包装到WPF兼容的属性中

public Thickness WPFSlicing
{
    get { return Slicing; }
    set
    {
        Slicing = value;
        OnPropertyChanged("Slicing");
    }
}

有没有更聪明的方法?我的父类中有许多属性,这似乎是一个非常缺乏灵感的方法。

这是一个非常有趣的问题

通常,我发现在MVVM应用程序中,您试图将一个模型作为视图模型的最终结果(产品/数据段)进行隔离。例如,如果您有一家自行车店,您会将店面视为视图,将销售人员视为视图模型(假设这是一辆根据订单定制的自行车),将模型视为成品自行车对象

在构建自行车的案例中,虽然它处于需要表示的“原型”阶段,但我倾向于将其封装在ViewModel中——因为其中包含逻辑。这似乎是一个额外的步骤,但最终,您可以在构建ViewModel时对其进行验证。如果您的模型不灵活,无法将INotifyPropertyChanged添加到其中(或者如果它是从服务生成的),那么如果您的自行车上有“0”个轮胎,就会出现问题——这应该会导致问题

很多人倾向于变得懒惰一些,将MVVM视为一种模式,将原型模型(数据输入在其中来回、更新)抽象为模型——而实际上它们应该是ViewModels

根据示例,我将有一个MVVM目录,如下所示:

Models
  -Bicycle (an object that can be passed across a service, etc -- data)
Views
  -BicycleCreatorView (the view or data template of the model)
  -StoreFrontView (the view of the entire store/app)
ViewModels
  -BicycleCreatorViewModel (the view model which CONSTRUCTS a Bicycle model as the end     result)
  -StoreFrontViewModel (the view model for the entire store)
现在,您可以很容易地让BicycleCreatorViewModel拥有一个构造函数,该构造函数接受自行车模型并预填充。这并不少见。有人可能会走进一家商店说,“嘿,你能把这个和另一个相似吗?这是它的样子。”虽然最终的结果是有另一个属性(可能只是一个get{})来实际渲染自行车对象,但如果验证是好的,并且我们没有0个轮胎、没有座椅(可能这是一个功能?),等等

因此,简而言之,出于这个目的,我总是将您的模型(如果您不能以任何方式扩展它)包装到它自己的ViewModel中。这将是真正的MVVM模式。您总是可以使用诸如ReactiveUI或其他可以包装属性的工具包之类的东西。您可能会花更多的时间来做这件事,但最终产品将比其他产品更灵活,更不容易出错。基本上你已经在这样做了,但是你可能会重写它,使它看起来“更干净”,并划清界限

从理论上讲,您还可以检查是否可以使用以下方法接近它:

您是否有可能使用面向方面的工具包?如果序列化是一个问题,可能会使您的类成为局部类,在扩展上包含INotifyPropertyChanged,然后XmlIgnore某些部分


问题是我们对模型的来源和使用方法知之甚少。希望这能帮助你或给你一个有趣的想法。我很想看看你是否提出了一个比标准更具“灵感”的解决方案。

我提供了另一种观点。这一切都可以用AOP框架(如PostSharp)非常简单地解决您所做的一切就是将[NotifyPropertyChanged]属性附加到您的类中,并且您的模型将所有内容连接起来

不过,请注意,这需要成本,但在国际海事组织看来,这可能是一项不错的投资

Ps,这是一个视图问题,但我认为让所有域模型类实现INotifyPropertyChanged没有任何错误。它不会降低性能,唯一的缺点是代码有点混乱。这就是我所做的,我的域模型实体从CommonEntityINotifyPropertyChanged实现。INotifyPropertyChanged不是WPF的一部分


它可以工作,而且肯定比在viewmodels中包装模型更好。

是的,您需要为每个setter调用PropertyChanged(“propertyName”):(视图、模型和视图模型似乎没有很好的分离。也许你可以编辑你的问题,以显示你的类中哪些与MVVM域中的哪些相对应。在模型中实现INotifyPropertyChanged不是很常见吗?你需要它。但也许你正在寻找它。如果你的VS版本支持宏(或),我发现录制一个宏来为我写出所有属性更改内容是最快的。如果你感兴趣,我有一个例子。谢谢你的长篇大论!实际上我甚至没有想到将
Model
作为
ParentClass
的ViewModel,但现在我想起来了,这就是它。我实际上只是一个intern和
ParentClass
是一个如果我碰了会让人非常生气的类哈哈。否则我肯定会研究
ParentClass
实现
INotifyPropertyChanged
我喜欢这个AOP解决方案,但是如果你的合同被锁定,你不能仅仅用标签来装饰合同。我同意AOP提供了很多f很酷的功能,但是如果你被锁定在你的模型来自于你无法控制的东西(比如一个带有契约的通信层DLL),唯一真正的选择就是构建一些东西