小试MVVM(2)
时间:2010-09-27 来源:DarthVader
上一次演示了如何设计View和ViewModel,这次重点是Model、ViewModel和View之间的交互。
源码可以从github上下载。
1、提取Model
一般的应用设计应该是先设计Model,然后才会设计View和ViewModel。现在我们在上一篇的基础上提取Model,代码如下:
ReaderModelpublic class ReaderModel : NotifyPropertyChangedHelper
{
public static readonly ReaderModel Instance = new ReaderModel();
private SyndicationFeed _selectedFeed;
private ReaderModel()
{
Feeds = new ObservableCollection<SyndicationFeed>();
}
public ObservableCollection<SyndicationFeed> Feeds { get; private set; }
public SyndicationFeed SelectedFeed
{
get { return _selectedFeed; }
set
{
_selectedFeed = value;
NotifyPropertyChanged("SelectedFeed");
Debug.WriteLine(SelectedFeed.Title.Text);
}
}
}
Model中保存了所有的Feed以及当前用户选择的Feed。Model采用了单例模式,实际应用中可以采用IoC容器实现依赖注入。
2、更改FeedsViewModel
在FeedsViewModel类中添加Model属性保存ReaderModel的实例,同时更改相应的属性行为,使用Model的对应属性,代码如下:
代码public ObservableCollection<SyndicationFeed> Feeds
{
get { return Model.Feeds; }
}
public SyndicationFeed SelectedFeed
{
get { return Model.SelectedFeed; }
set { Model.SelectedFeed = value; }
}
public ReaderModel Model { get; set; }
3、实现FeedItemsViewModel
FeedItemsView显示每个新闻标题,FeedItemsViewModel中对应的就是Items属性。FeedItemsViewModel还要监视ReaderModel中SelectedFeed属性的变化,当用户选择不同的Feed时,要及时更新Items,代码如下:
FeedItemsViewModelpublic class FeedItemsViewModel : NotifyPropertyChangedHelper
{
private readonly ReaderModel _model = ReaderModel.Instance;
public FeedItemsViewModel()
{
_model.PropertyChanged += delegate(object sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == "SelectedFeed")
{
if (_model.SelectedFeed != null)
{
Items = _model.SelectedFeed.Items;
NotifyPropertyChanged(() => Items);
}
}
};
}
public IEnumerable<SyndicationItem> Items { get; private set; }
}
4、绑定View和ViewModel
首先绑定FeedsView中ListBox的SelectedItem到FeedsViewModel的SelectedFeed属性
<ListBox Grid.Row="2" ItemsSource="{Binding Feeds}" SelectedItem="{Binding SelectedFeed, Mode=TwoWay}">
注意要双向绑定
然后在FeedItemsView中添加ListBox并绑定到FeedItemsViewModel的Items属性
<ListBox ItemsSource="{Binding Items}">
最后可以参考上一篇为FeedItemsView添加设计数据。
运行时的效果如下:
总结
相对于上一篇,这次没有太多的代码可以演示,最主要的还是Model以及通过Model和ViewModel更新UI。
这个小例子只是演示了基本的MVVM的结构,以后我还会试验一些其他与MVVM相关的技术。