返回51飞艇冠军计划
当前位置: 主页 > 网络编程 > .Net实例教程 >

在Silverlight中应用MVVM模式教程代码

时间:2012-02-11 18:31来源:知行网www.penoybetterlife.com 编辑:麦田守望者

MVVM:即Model View ViewModel三层,

个人感觉归根结底MVVM其实就是MVC的一个变种,ViewModel有一个很明显的优点:可降低View->Control的偶合,像Flash/Silverlight这类RIA应用,在View层中会有不少实现动画效果的代码,而传统的MVC结构,在实现数据更新时,不可避免地要在View中写很多Control代码,这样的话容易造成结构混乱,

但MVVM基于事件绑定机制,在View层中只要完成绑定即可,View会自动更新Model,Model再通知Control,这样就可大量减少View层中的Control代码。

下面举个例子说明:
 

在Silverlight中应用MVVM模式教程代码
 

51飞艇冠军计划我们这里有一个可分组的DataGrid控件,现在的需求是: 当用户单击Complete时,实现一些控制操作,如更新某个图表,或更新后台数据库等。

首先:我们需要创建一个Model,此Model继承INotifyPropertyChanged接口,会强制实现PropertyChangedEventHandler事件即属性更改事件,在Complete的值发生改变时(View->Model)冒出这个事件。

//Model public class Task :INotifyPropertyChanged { public string ProjectName { get; set; } public string TaskName { get; set; } public DateTime DueDate { get; set; } // Private task data. private bool m_Complete = false; public bool Complete { get { return this.m_Complete; } set { if (value != this.m_Complete) { this.m_Complete = value; NotifyPropertyChanged("Complete"); } } } public string Notes { get; set; } #region INotifyPropertyChanged 成员 public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion } 然后: 我们需要在Control层中生成绑定数据源,并在数据源上侦听这个属性更改事件(Model->Control),由于多用到泛型集合,所以我们希望在对象被加入集合列表(List)时自动绑定这个事件,因此我们新建一个类以简化这个操作,事实上ObservableCollection中已经包含了PropertyChangedEventHandler事件 ,可能是出于性能的考虑,将其设为了protected类型,并且没有进行任何操作,因此我们需要新建一个子类来实现他: public class ViewModelCollection<T> : ObservableCollection<T> { public ViewModelCollection():base() { } public new void Add(T item) { //在添加时自动绑定 ((INotifyPropertyChanged)item).PropertyChanged += new PropertyChangedEventHandler(ViewModelCollection_PropertyChanged); base.Add(item); } #region INotifyPropertyChanged 成员 public new event PropertyChangedEventHandler PropertyChanged; void ViewModelCollection_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (PropertyChanged != null) { //继续向上冒出事件,并传递发生改变的对象 PropertyChanged(sender, new PropertyChangedEventArgs(e.PropertyName)); } } #endregion } 接着: 我们就可以在ViewModel中使用这个泛型集合了,并添加对属性更改事件的侦听。 这里使用的PagedCollectionView对象仅仅是为DataGrid控件提供分组数据源,这也是一个相当强大的类,大家可以查阅相当文档学习他的使用。 //ViewModel public class ViewModel { public PagedCollectionView TaskBinding() { // 生成泛型集合数据源。 ViewModelCollection<Task> taskList = new ViewModelCollection<Task>(); for (int i = 1; i <= 14; i++) { taskList.Add(new Task() { ProjectName = "Project " + ((i % 3) + 1).ToString(), TaskName = "Task " + i.ToString(), DueDate = DateTime.Now.AddDays(i), Complete = (i % 2 == 0), Notes = "Task " + i.ToString() + " is due on " + DateTime.Now.AddDays(i) + ". Lorum ipsum..." }); } taskList.PropertyChanged += new PropertyChangedEventHandler(taskList_PropertyChanged); PagedCollectionView taskListView = new PagedCollectionView(taskList); // 添加要进行分组的属性 taskListView.GroupDescriptions.Add(new PropertyGroupDescription("ProjectName")); taskListView.GroupDescriptions.Add(new PropertyGroupDescription("Complete")); return taskListView; } void taskList_PropertyChanged(object sender, PropertyChangedEventArgs e) { Task task = (Task)sender; MessageBox.Show(string.Format("Model Changed: IsComplete={0} PropertyName={1}", task.Complete, e.PropertyName)); //其他一些操作,如更新数据库,图表等 } }
最后: 我们就可以在View层中进行数据绑定了
public partial class MainPage : UserControl
{
private ViewModel controller;

public MainPage()
{
InitializeComponent();

controller = new ViewModel();
dataGrid1.ItemsSource = controller.TaskBinding();
}
}

51飞艇冠军计划 最后看一看效果:当用户单击Complete列的选择框时就会触发Control中的控制代码,从而不需要在View中书写额外的代码

 


完整代码:
xaml文件:
<UserControl x:Class="DataGridGrouping.MainPage"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="600" Height="500">
<Grid x:Name="LayoutRoot" Background="White" Margin="10">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<data:DataGrid x:Name="dataGrid1">
<data:DataGrid.RowGroupHeaderStyles>
<!-- Style for groups at top level -->
<Style TargetType="data:DataGridRowGroupHeader">
<Setter Property="PropertyNameVisibility" Value="Collapsed" />
<Setter Property="Background" Value="#FF112255" />
<Setter Property="Foreground" Value="#FFEEEEEE" />
<Setter Property="SublevelIndent" Value="15" />
</Style>
<!-- Style for groups under the top level -->
<Style TargetType="data:DataGridRowGroupHeader">
<Setter Property="Background" Value="#44225566" />
</Style>
</data:DataGrid.RowGroupHeaderStyles>
</data:DataGrid>
</Grid>
</UserControl>


CS:文件:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Collections.Specialized;
using System.Collections.Generic;

namespace DataGridGrouping
{
public partial class MainPage : UserControl
{
private ViewModel controller;

public MainPage()
{
51飞艇冠军计划 InitializeComponent();

controller = new ViewModel();
dataGrid1.ItemsSource = controller.TaskBinding();
}
}

//ViewModel
public class ViewModel
{
public PagedCollectionView TaskBinding()
{
// 生成泛型集合数据源。
ViewModelCollection<Task> taskList = new ViewModelCollection<Task>();
for (int i = 1; i <= 14; i++)
{
taskList.Add(new Task()
{
ProjectName = "Project " + ((i % 3) + 1).ToString(),
TaskName = "Task " + i.ToString(),
DueDate = DateTime.Now.AddDays(i),
Complete = (i % 2 == 0),
Notes = "Task " + i.ToString() + " is due on "
+ DateTime.Now.AddDays(i) + ". Lorum ipsum..."
});
}
51飞艇冠军计划 taskList.PropertyChanged += new PropertyChangedEventHandler(taskList_PropertyChanged);

PagedCollectionView taskListView = new PagedCollectionView(taskList);
// 添加要进行分组的属性
taskListView.GroupDescriptions.Add(new PropertyGroupDescription("ProjectName"));
taskListView.GroupDescriptions.Add(new PropertyGroupDescription("Complete"));

return taskListView;
}

void taskList_PropertyChanged(object sender, PropertyChangedEventArgs e)

------分隔线----------------------------
标签(Tag):C# C#实例教程 c#基础教程 C#源代码 c#技巧
------分隔线----------------------------
推荐内容
猜你感兴趣