在WP8开发中的使用MVVM模式

MVVM模式,即Model - View - ViewModel模式,这是Microsoft推荐WPF开发者使用的一种模式。

MVVM模式的目的是为了使View(即xaml)只处理UI效果,与数据相关的操作都由ViewModel处理,代码结构更清晰,容易维护。

要深入理解MVVM模式,推荐阅读这篇 章:

http://www.codeproject.com/KB/WPF/WpfMvvmQuickStart.aspx


而实际开发中实现这个模式,推荐使用一个开源辅助toolkit:mvvmlight

toolkit源代码在这里:

http://mvvmlight.codeplex.com/


如下例,mvvmlight的使用重点是把控件Event通过EventToCommand转换为Command交由ViewModel处理数据,数据处理完毕后如果需要通知View进行效果动画或者页面跳转之类的纯UI操作,则可以在ViewModel的Command里向View发送一个Message,View通过注册该类型Message就可以接收到该Message,然后进行纯UI处理。

当然,如果控件事件响应时只有纯粹UI效果处理而不牵涉到数据,那么就没必要使用繁琐的EventToCommand转换为Command交给ViewModle,还是在xaml.cs里注册该事件处理吧,不要为了死模式而不变通。


mvvmlight简单使用方法例子:

以wp8默认创建的pivot application为例,以下修改框架生成的ItemViewModel为:

using GalaSoft.MvvmLight;

namespace PivotApp.ViewModels
{
	public class ItemViewModel : ViewModelBase
	{
		private string _lineOne;
		public string LineOne
		{
			get
			{
				return _lineOne;
			}
			set
			{
				if (value != _lineOne)
				{
					_lineOne = value;
					RaisePropertyChanged("LineOne");
				}
			}
		}

		private string _lineTwo;
		public string LineTwo
		{
			get
			{
				return _lineTwo;
			}
			set
			{
				if (value != _lineTwo)
				{
					_lineTwo = value;
					RaisePropertyChanged("LineTwo");
				}
			}
		}

		private string _lineThree;
		public string LineThree
		{
			get
			{
				return _lineThree;
			}
			set
			{
				if (value != _lineThree)
				{
					_lineThree = value;
					RaisePropertyChanged("LineThree");
				}
			}
		}
	}
}

将框架生成的MainViewModel修改为:

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System.Collections.ObjectModel;

namespace PivotApp.ViewModels
{
	public class MainViewModel : ViewModelBase
	{
		public MainViewModel()
		{
			this.Items = new ObservableCollection<ItemViewModel>();
			ItemClickCommand = new RelayCommand<object>(OnItemClick);
		}

		public ObservableCollection<ItemViewModel> Items { get; private set; }

		public bool IsDataLoaded
		{
			get;
			private set;
		}

		public RelayCommand<object> ItemClickCommand { get; private set; }
		private void OnItemClick(object selectedItem)
		{
			if (selectedItem != null && (selectedItem as ItemViewModel) != null)
			{
				(selectedItem as ItemViewModel).LineOne += "+";
			}
			Messenger.Default.Send<NotificationMessage>(new NotificationMessage("OnItemClick"));
		}

		public void LoadData()
		{
			// 示例数据;替换为实际数据
			this.Items.Add(new ItemViewModel() { LineOne = "runtime one", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime two", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime three", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime four", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime five", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime six", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime seven", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime eight", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime nine", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime ten", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime eleven", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime twelve", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime thirteen", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime fourteen", LineTwo = "Dictumst eleifend facilisi faucibus", LineThree = "Pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime fifteen", LineTwo = "Habitant inceptos interdum lobortis", LineThree = "Accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat" });
			this.Items.Add(new ItemViewModel() { LineOne = "runtime sixteen", LineTwo = "Nascetur pharetra placerat pulvinar", LineThree = "Pulvinar sagittis senectus sociosqu suscipit torquent ultrices vehicula volutpat maecenas praesent accumsan bibendum" });

			this.IsDataLoaded = true;
		}
	}
}

把MainPage.xaml里第一个LongListSelector的SelectionChanged事件转换成Command交由ViewModel处理:

				<phone:LongListSelector Name="longList1"
										Margin="0,0,-12,0"
										ItemsSource="{Binding Items}">
					<i:Interaction.Triggers>
						<i:EventTrigger EventName="SelectionChanged">
							<cmd:EventToCommand Command="{Binding ItemClickCommand}"
							CommandParameter="{Binding SelectedItem, ElementName=longList1}">
							</cmd:EventToCommand>
						</i:EventTrigger>
					</i:Interaction.Triggers>
					<phone:LongListSelector.ItemTemplate>
						<DataTemplate>
							<StackPanel Margin="0,0,0,17">
								<TextBlock Text="{Binding LineOne}"
										   TextWrapping="Wrap"
										   Style="{StaticResource PhoneTextExtraLargeStyle}" />
								<TextBlock Text="{Binding LineTwo}"
										   TextWrapping="Wrap"
										   Margin="12,-6,12,0"
										   Style="{StaticResource PhoneTextSubtleStyle}" />
							</StackPanel>
						</DataTemplate>
					</phone:LongListSelector.ItemTemplate>
				</phone:LongListSelector>

以上,xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"

上面代码有个错误,SelectedItem在Command触发之后才被LongListSelector修改,所以每次拿到的都是上一次Selection的值,可以改为使用PassEventArgsToCommand传递EventArgs


在MainPage.xaml.cs的成员函数如下:

		public MainPage()
		{
			InitializeComponent();
			DataContext = App.ViewModel;
		}

		// 为 ViewModel 项加载数据
		protected override void OnNavigatedTo(NavigationEventArgs e)
		{
			if (!App.ViewModel.IsDataLoaded)
			{
				App.ViewModel.LoadData();
			}
			Messenger.Default.Register<NotificationMessage>(this, HandleNotificationMessage);
		}

		protected override void OnNavigatedFrom(NavigationEventArgs e)
		{
			Messenger.Default.Unregister(this);
		}

		private void HandleNotificationMessage(NotificationMessage msg)
		{
			longList1.SelectedItem = null;
			this.NavigationService.Navigate(new Uri("/NextPage.xaml", UriKind.Relative));
		}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值