MVFM框架----示例
来源:互联网 发布:微信头像 知乎 编辑:程序博客网 时间:2024/06/13 08:58
本章介绍mvfm的详细使用方法,并提供win8下的demo以供参考。
用VS2012建立工程,选择windows应用商店中的网格应用程序。本次的demo就是将这个vs2012自带的示例改造成mvfm方式运行。
由于这个示例已经有了view和model层(SampleDataSource类),这两块就不需要重写了,我们直接开始构造fuction model。
首先引入Windows.UI.Interactivity类库,这个库是微软提供的一个扩展库,需要从NuGet下载安装。
然后再引入mvfm库,这是mvfm开发模式所依赖的动态库。
构建function model,代码如下:
public class SampleFunctionModel : FunctionModelBase { #region Property IEnumerable<SampleDataGroup> _groups; public IEnumerable<SampleDataGroup> Groups { get { if (_groups == null) _groups = SampleDataSource.GetGroups("AllGroups"); return _groups; } } SampleDataGroup _currentGroup; public SampleDataGroup CurrentGroup { get { return _currentGroup; } set { this.SetProperty(ref _currentGroup, value); } } SampleDataItem _currentItem; public SampleDataItem CurrentItem { get { return _currentItem; } set { this.SetProperty(ref _currentItem, value); } } #endregion #region Command public ActionCommand<object> SetCurrentGroupCommand { get; private set; } public ActionCommand<object> SetCurrentItemCommand { get; private set; } #endregion #region Command Function void SetCurrentGroup(object parameter) { var Group = (parameter as ExCommandParameter).Parameter as SampleDataGroup; if (Group != null) CurrentGroup = Group; } void SetCurrentItem(object parameter) { var Item = (parameter as ExCommandParameter).Parameter as SampleDataItem; if (Item != null) { CurrentItem = Item; } } #endregion #region Public Function #endregion #region Private Function #endregion #region protected Function protected override void InitializeData() { SetCurrentGroupCommand = new ActionCommand<object>(SetCurrentGroup); SetCurrentItemCommand = new ActionCommand<object>(SetCurrentItem); } #endregion }其中Groups是整个工程的数据源,Groups从SampleDataSource中获取,并交由view曾显示。mvfm中function model并不存储数据,只负责业务逻辑处理,function model仅保存临时数据。例如CurrentGroup和CurrentItem,这两个属性分别代表当先选择或显示的SampleDataGroup和SampleDataItem。还需要说明一点的时,有些UI逻辑放在页面里处理,并不放在function model中。像页面跳转这样的常用ui逻辑都放在界面中处理。
SetCurrentGroupCommand和SetCurrentItemCommand分别代表设置当前的SampleDataGroup命令和当前的SampleDataItem命令。将逻辑封装成命令进行交互称作命令模式,mvfm中view与function model的绝大部分交互都通过这种模式进行。
在InitializeData函数中指定了具体执行命令的函数,SetCurrentGroupCommand由SetCurrentGroup函数执行。所有的命令都是ICommand类型,而ActionCommand<T>则是将ICommand封装了,方便使用。
下面看看SetCurrentGroup中德代码。若界面上有参数传过来,都将是ExCommandParameter这种类型,下面是ExCommandParameter类的代码:
public class ExCommandParameter { /// <summary> /// 事件触发源 /// </summary> public object Sender { get; set; } /// <summary> /// 事件参数 /// </summary> public object EventArgs { get; set; } /// <summary> /// 额外参数 /// </summary> public object Parameter { get; set; } /// <summary> /// 额外参数 2 /// </summary> public object Parameter2 { get; set; } /// <summary> /// 额外参数 3 /// </summary> public object Parameter3 { get; set; } }其中Sender为发送着,比如控件之类的,EventArgs则是某些代理中德事件参数,比如这个命令是button的click触发的,则EventArgs是对应的RoutedEventArgs事件。Parameter则是附带额外的参数,最多可以带三个。
各位看到这里可能对function model还有些迷惑,等看完xaml中德处理在回头看就好理解了。
function model写完后在APP中声明 function model的资源:
<x:String x:Key="AppName">MvfmText</x:String>
这样就可以在其他的页面中使用function model中Command了。
首先看GroupedItemsPage页面,删光cs中德代码,仅保留构造函数
public sealed partial class GroupedItemsPage : MvfmText.Common.LayoutAwarePage { public GroupedItemsPage() { this.InitializeComponent(); } }在xaml页中声明数据源
<common:LayoutAwarePage x:Name="pageRoot" x:Class="MvfmText.GroupedItemsPage" DataContext="{StaticResource SampleFunctionModel}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MvfmText" xmlns:data="using:MvfmText.Data" xmlns:common="using:MvfmText.Common" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mvfm="using:Mvfm" xmlns:i="using:Windows.UI.Interactivity" mc:Ignorable="d">
DataContext就是数据源,数据从SampleFunctionModel中获取。特别注意 xmlns:mvfm="using:Mvfm"和 xmlns:i="using:Windows.UI.Interactivity"这两条语句,xaml与function将同过这两个命名空间进行。
然后声明网格所需要使用的数据资源
<Page.Resources> <!-- 此页所显示的分组项的集合,绑定到完整 项列表的子集,因为无法虚拟化组中的项 --> <CollectionViewSource x:Name="groupedItemsViewSource" Source="{Binding Groups}" IsSourceGrouped="true" ItemsPath="TopItems" d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/> </Page.Resources>其中Groups就是SampleFunctionModel中的Groups属性。
然后再造GridView:
<GridView x:Name="itemGridView" AutomationProperties.AutomationId="ItemGridView" AutomationProperties.Name="Grouped Items" Grid.RowSpan="2" Padding="116,137,40,46" ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}" ItemTemplate="{StaticResource Standard250x250ItemTemplate}" SelectionMode="None" IsSwipeEnabled="false" IsItemClickEnabled="True"> <i:Interaction.Triggers> <i:EventTrigger EventName="ItemClick"> <mvfm:EventArgNameCommandAction EventArgName="ClickedItem" Command="{Binding SetCurrentItemCommand}"/> <local:NavigateAction NavigateName="MvfmText.ItemDetailPage"/> <!--<mvfm:NavigateAction NavigateName="MvfmText.ItemDetailPage"/>--> </i:EventTrigger> </i:Interaction.Triggers> </GridView>GridView自带的属性设置就不说明了,重点介绍
<i:Interaction.Triggers> <i:EventTrigger EventName="ItemClick"> <mvfm:EventArgNameCommandAction EventArgName="ClickedItem" Command="{Binding SetCurrentItemCommand}"/> <local:NavigateAction NavigateName="MvfmText.ItemDetailPage"/> </i:EventTrigger> </i:Interaction.Triggers>
这几行语句。Triggers,Behavior,Action是mvfm所依赖的核心技术中德3个。Triggers为触发器,Behavior为行为附加,Action则负责执行某些命令。Triggers往往与Action相伴出现,通过控件中的某些行为或event触发执行Action。
这几行语句中EventTrigger指定由GridView中的ItemClick事件触发,触发的Action分别为NavigateAction和EventArgNameCommandAction。NavigateAction执行导航,NavigateName参数指定导航页,此Action触发后界面将直接跳转到ItemDetailPage页面。也就是说若点击了GridView中的某一项,界面就会跳转到ItemDetailPage页。EventArgNameCommandAction中的Command指定所要执行的命令,这里则指定了执行SampleFunctionModel中的SetCurrentItemCommand命令。EventArgName参数指定将EventArg中的哪个属性作为参数传递到Command中。
然后看下HeaderTemplate中的代码:
<GroupStyle.HeaderTemplate> <DataTemplate> <Grid Margin="1,0,0,6"> <Button AutomationProperties.Name="Group Title" Style="{StaticResource TextPrimaryButtonStyle}" > <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" /> <TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/> </StackPanel> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <mvfm:ExInvokeCommandAction Command="{Binding SetCurrentGroupCommand, Source={StaticResource SampleFunctionModel}}" CommandParameter="{Binding}"/> <local:NavigateAction NavigateName="MvfmText.GroupDetailPage"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </DataTemplate></GroupStyle.HeaderTemplate>注意其中的这几行语句
<i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <mvfm:ExInvokeCommandAction Command="{Binding SetCurrentGroupCommand, Source={StaticResource SampleFunctionModel}}" CommandParameter="{Binding}"/> <local:NavigateAction NavigateName="MvfmText.GroupDetailPage"/> </i:EventTrigger> </i:Interaction.Triggers>原理与前面是一样的,主要说明下ExInvokeCommandAction, ExInvokeCommandAction中Command指定的是完整的Command路径,这样的好处在于不管Action在何处声明,都可以执行到functiong model中的命令。 其中CommandParameter则是将自身的数据源作为参数传输到了执行对应命令的函数中,此命令对应的是如下函数
void SetCurrentGroup(object parameter) { var Group = (parameter as ExCommandParameter).Parameter as SampleDataGroup; if (Group != null) CurrentGroup = Group; }剩下两个页面就不额外说明了,原理差不多,运行后你会发现执行效果和原来没有任何差别。由于page对应的.cs中不需要写人和代码,这将大大减轻我们的工作量,并且这样的边写方式易于修改,当需求频繁变化是也能轻松应对。
并且我们还有两个原model中提供的两个函数没有用到,GetGroup和GetItem完全没用用武之地了,因为我们可以从页面中直接获取对应的数据,并在另一个页面中使用,这样省去了页面间的参数传递以及部分数据处理逻辑。这样轻松的编程方式
你还有什么理由拒绝呢?以后我会介绍mvfm的高级用法,熟练使用以后编写代码效率将会大大提高。
示例代码在本人空间资源中
- MVFM框架----示例
- MVFM框架----概述
- MVFM框架----模块间最大化解耦之广播监听模式
- HTML框架(Frame)示例
- html框架示例
- SSH框架整合示例
- Glut框架示例
- SSH框架整合示例
- ssh框架整合示例
- DWR框架--示例
- spring 框架示例过程
- SSH框架整合示例
- SSH框架整合示例
- SSH2框架搭建示例
- frame框架简单示例
- struts2框架入门示例
- Spring框架基础示例
- HTML框架集示例
- 多核DSP C6678下CCS5.2 环境下分析L1P,L1D,L2 cache的方法
- 随机生成密码
- ssh架构原理
- 小波变换--matlab中系数的获取
- Codeforces Round #170
- MVFM框架----示例
- 多核DSP C6678 SRIO借口调试笔记
- 关于多核DSP C6678共享存储器问题的理解
- vs2008下win32 dll封装笔记
- join使用
- Singleton单例类
- 小技巧,网页添加音乐播放器
- RedHat9.0 vs-ftp 基本设置
- HP大中华区总裁孙振耀退休感言