2014-10-07 212 views
2

我已经阅读了一些针对此问题的stackoverflow上的问题,但没有发现实际上提供了一个正确的方法。我只是对我的实施感觉不对。MVVM - 模型之间的关系

鉴于以下情况: 我收到了包含曲目的播放列表(例如音乐播放列表)。

class PlaylistModel
-> string Name // Name of the playlist
-> List<TrackModel> Tracks // tracks contained by the playlist

class TrackModel
-> string Name

鉴于这个方案,我将如何映射这种关系,如果我的视图模型显示播放列表和相关联的轨道为可能用户在改变一个TreeView相互作用?

我已经想过的关系,并最终使用是这样的:

public class PlaylistViewModel : ViewModelBase 
{ 
    private PlaylistModel _Playlist; 
    public PlaylistModel Playlist 
    { 
     get { return _Playlist; } 
     set 
     { 
      if (_Playlist == value) return; 
      _Playlist = value; 
      NotifyOfPropertyChange(() => Playlist); 
     } 
    } 

    public ObservableCollection<TrackViewModel> Tracks 
    { 
     get { return new ObservableCollection<TrackViewModel>(Playlist.Tracks.Select(track => new TrackViewModel(track))); } 
     set 
     { 
      var tracksCollection = new ObservableCollection<TrackViewModel>(Playlist.Tracks.Select(track => new TrackViewModel(track))); 
      if (tracksCollection == value) return; 
      Playlist.Tracks = new List<TrackModel>(value.Select(trackViewModel => trackViewModel.Track)); 
      NotifyOfPropertyChange(() => Tracks); 
     } 
    } 

    public string Name 
    { 
     get { return Playlist.Name; } 
     set 
     { 
      if (Playlist.Name == value) return; 
      Playlist.Name = value; 
      NotifyOfPropertyChange(() => Name); 
     } 
    } 
} 

(只包含基本码部分)

您可能已经注意到周围的_Playlist.Tracks财产是铸造键入TrackModel。这是这个问题。我只是可以在TrackModel类中实现INotifyPropertyChanged,但我也不太关心这个问题,因为它不仅仅是我的UI交互层。

回答

2

请参阅this discussion用于在模型,视图模型或两者中实现INotifyPropertyChanged。

如果您有以下

  1. 加载播放列表从服务器相匹配的工作流程
  2. 用户修改播放列表
  3. 用户要么保存播放列表或放弃修改

,你也可以考虑保持你的模型没有INotifyPropertyChanged,并利用AutoMapper从模型转换到视图模型(加载)和视图模型到模型(保存)。

Another post关于此事。

+0

实现INotifyPropertyChanged的东西实际上是一个ViewModel,因为唯一真正预订属性更改通知的是视图绑定。只有ViewModel(并且没有Model)的应用程序没有任何问题 - “模型”可以内置类似集合等。如果您发现需要添加大量的非视图特定逻辑,最好将模型与视图模型分开。 – 2014-10-07 18:47:33

+0

嘿,谢谢你的回答。在讨论中偶然发现了这个评论:“如果模型中的财产发生变化,你会怎么做?您需要以某种方式将其传送到视图模型。诚实的问题,我现在正在处理这个难题。“根据最高票数,这似乎是常用的?基本上这就是我在这个确切的例子中面临的问题。 – 0x8BADF00D 2014-10-07 18:48:11

+0

@PeterRitchie如果我有一个类表示我的域中的实体,它使用从数据库接收的数据填充,并且包含作用于该数据的业务逻辑,该类是模型。如果它实现INotifyPropertyChanged,它仍然是一个模型。如果同一个类然后直接绑定到视图的DataContext,那么我相信它是一个模型和一个视图模型。 – 2014-10-07 19:01:03