7

我在我的 wpf MVVM(基于 Prism)应用程序中面临一些设计问题,很乐意得到您的建议。我的模型很简单:

public class Customer
{
   public string FirstName {get;set;}
   public string LastName {get;set;}
}

如您所见,我的 Model 类没有任何 INotifyPropertyChnaded 支持。我还有用于 CustomerDetails 屏幕的 ViewModel,它支持 INotifyPropertyChanged。

public class CustomerDetailsViewModel:INotifyPropertyChanged /*Or NotificationObject*/
{
   /*INotifyPropertyChanged event */
   private Customer item;
   public Customer Item
   {
      get{return item;}
      set
      {
         item=value; 
         //Raise PropertyChanged
         //Set IsDirty to true
      }
   }
}

在我看来,我正在使用绑定到 Item.FirstName 并且我的 ViewModel 正在更新。我的问题是 - 因为只有 FirstName 属性正在通过 View 更新,并且模型本身不支持 INotifyPropertyChanged,因此没有调用 Item 设置器,并且 IsDirty 仍然等于 false(因此不会更新 IsDirty 通知用户界面)。

我知道我可以在模型中支持 INotifyPropertyChanged,然后在视图模型中注册到 Item.PropertyChanged 事件,并实际将 IsDirty 设置为 true,但是 - 由于我也在使用 CodeFirst,并且我的 Model 类在我的 ServerSide 之间共享和我的客户端(不使用添加服务参考),我不想将 INotifyPreoprtyChanged 的​​东西添加到我的服务器端。

我正在考虑创建新项目,该项目将使用 T4 模板一一复制我的所有实体(作为客户),并为每个模型添加 INotifyPropertyChanged 支持。这看起来合理还是不合理?还有其他建议吗?

谢谢!

4

5 回答 5

4

选项1。
将在客户端和服务器 (DTO) 之间传输的实体与作为客户端模型的实体分开。INPC在模型中实现。在这些实体之间使用映射。

选项 2。
仅将视图绑定到视图模型属性。制作视图模型属性,它包装了相应的模型属性。

选项 3。
是前两个选项的混合。不要在视图模型中聚合模型。使用模型和视图模型之间的映射。制作与模型属性相对应的视图模型属性。

于 2013-02-14T07:47:56.477 回答
1

那么你的方法根本不是最好的。更好的是使用这样的VM


public class CustomerDetailsViewModel : INotifyPropertyChanged
{
  public CustomerDetailsViewModel(Customer customer)
  {
    _item = customer;
  }
  private Customer _item;

  public string FirstName
  { 
    get { return _item != null ? _item.FirstName : null; }
    set 
    {
      if (_item == null)
        _item = new Customer(); // just an example, probably it's not the desired behavior
      _item.FirstName = value;
      RaisePropertyChanged(...);
    }
  }
  ...
}

这将坚持 MVVM 的精神。

于 2013-02-14T07:52:32.173 回答
1

如果您希望您的 UI 注意到您的模型属性何时发生更改,您的模型类必须实现INotifyPropertyChanged和类似的 MVVM 接口(IDataErrorInfo等...),以便Notifyproperty changed.

这是因为您并不总是从视图模型更新模型,您必须在视图模型中实现INotifyProperyChanged并通知更改。

当您无法INotifyPropertyChanged在模型类中实现时,将相应的模型属性包装在使用的视图模型中,这会使视图模型增长非常快并创建不必要的代码重复。

场景例如:

public class Customer
{
   public string FirstName {get;set;}
   public string LastName {get;set;}

   // Changes the first name.
   public void ChangeFirstName(string newName)
   {
      FirstName = newName;
      //The UI will never know that the property changed, and it won't update.
   }
}

解决方案:

INotifyPropertyChanged在您的模型类中实现,创建backing fields您的properties,并为每个属性setter,在set操作之后,使用名称引发OnPropertyChanged调用的方法property

于 2015-02-27T15:44:18.767 回答
0

如果您不喜欢使用 INotifyPropertyChanged 代码使模型混乱,您可以尝试使用名为 PropertyChanged.Fody 的 NUGet 包

你可以这样使用它;

using PropertyChanged;

[ImplementPropertyChanged]
public class Customer
{
   public string FirstName {get;set;}
   public string LastName {get;set;}
}

此类中的任何公共属性现在都将支持 INotifyPropertyChanged

于 2016-11-04T16:27:36.937 回答
-1

我认为你在正确的轨道上。在服务器端,您不需要INotifyPropertyChanged,因此不要将其添加到服务器端的域类中。

您可以在客户端项目中添加一些构建符号,例如“WPF”;并且在代码优先定义中INotifyPropertyChanged仅在存在“WPF”构建符号时才实现。然后只需将您的服务器端域类添加为您的演示应用程序的链接。就像是;

#if WPF
public class MyEntity : INotifyPropertyChanged
#else
public class MyEntity

....
于 2013-02-14T07:50:55.473 回答