WP8 MVVM设计模式
类似了Android里边的MVC模式, Windows Phone 有自己的Model-View-ViewModel模式,这种模式的作用就是为了Data和UI分离开来。
如果你英文较好的话,你可以不再阅读以下内容,直接访问 WindowsPhone Dev Center学习阅读,因为以下内容是对其的一个中文复述。
这次演练,将执行以下的任务:
- 创建一个Model、一个ModelView和两个View;
- 使用XAML文件绑定数据;
- 创建一个定制数据的转换器;
- 保留页面的数据;
- 在isolated storage保存数据;
- 使用App Bar暴露保存的功能。
创建一个Model、一个ModelView和两个View
- 右击MVVMTestApp->Add->New folder 添加Model、ModelView和View文件夹如下:

- 右击Model->Add->class 新建数据Model,命名为Accomplishment.cs, 添加内容如下:
using System;
using System.ComponentModel; namespace MVVMTestApp.Model
{
public class Accomplishment : INotifyPropertyChanged
{
// The name of the accomplishment.
public string Name { get; set; } // The type of the accomplishment, Item or Level.
public string Type { get; set; } // The number of each item that has been collected.
private int _count;
public int Count
{
get
{
return _count;
}
set
{
_count = value;
RaisePropertyChanged("Count");
}
} // Whether a level has been completed or not
private bool _completed;
public bool Completed
{
get
{
return _completed;
}
set
{
_completed = value;
RaisePropertyChanged("Completed");
}
} public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
} // Create a copy of an accomplishment to save.
// If your object is databound, this copy is not databound.
public Accomplishment GetCopy()
{
Accomplishment copy = (Accomplishment)this.MemberwiseClone();
return copy;
}
}
}
当某个属性改变的时候,这个类通过执行INotifyPropertyChanged接口,使用PropertyChanged事件通知绑定了(OneWay或者TwoWay绑定)这个属性的View更新数据。
- 右击Model->Add->class 新建数据ViewModel,命名为ViewModel.cs,它是连接View和Model的一个中枢。 现添加内容如下:
using System;
using System.Windows;
using System.Collections.ObjectModel;
using System.IO.IsolatedStorage;
using MVVMTestApp.Model; namespace MVVMTestApp.ViewModelNamespace
{
public class ViewModel
{
public ObservableCollection<Accomplishment> Accomplishments { get; set; } public void GetAccomplishments()
{
if (IsolatedStorageSettings.ApplicationSettings.Count > )
{
GetSavedAccomplishments();
}
else
{
GetDefaultAccomplishments();
}
} public void GetDefaultAccomplishments()
{
ObservableCollection<Accomplishment> a = new ObservableCollection<Accomplishment>(); // Items to collect
a.Add(new Accomplishment() { Name = "Potions", Type = "Item" });
a.Add(new Accomplishment() { Name = "Coins", Type = "Item" });
a.Add(new Accomplishment() { Name = "Hearts", Type = "Item" });
a.Add(new Accomplishment() { Name = "Swords", Type = "Item" });
a.Add(new Accomplishment() { Name = "Shields", Type = "Item" }); // Levels to complete
a.Add(new Accomplishment() { Name = "Level 1", Type = "Level" });
a.Add(new Accomplishment() { Name = "Level 2", Type = "Level" });
a.Add(new Accomplishment() { Name = "Level 3", Type = "Level" }); Accomplishments = a;
//MessageBox.Show("Got accomplishments from default");
} public void GetSavedAccomplishments()
{
ObservableCollection<Accomplishment> a = new ObservableCollection<Accomplishment>(); foreach (Object o in IsolatedStorageSettings.ApplicationSettings.Values)
{
a.Add((Accomplishment)o);
} Accomplishments = a;
//MessageBox.Show("Got accomplishments from storage");
}
}
}
- 右击View->New Item->Windows Phone User Control新建第一个View,命名为ItemView.xaml,在GRID布局里边添加如下内容:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="Item" Text="{Binding Path=Name, Mode=OneWay}" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBox x:Name="Count" Text="{Binding Path=Count, Mode=TwoWay}" Grid.Column="1" TextAlignment="Center" InputScope="Number"/>
<TextBlock x:Name="Check" Text="{Binding Path=Count, Mode=OneWay}" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
- 右击View->New Item->Windows Phone User Control新建第二个View,命名为LevelView.xaml,右击xaml->,替换一下内容:
using System;
using System.Windows.Controls;
using System.Globalization; namespace MVVMTestApp.View
{
public partial class LevelView : UserControl
{
public LevelView()
{
InitializeComponent();
}
} public class BoolOpposite : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool b = (bool)value;
return !b;
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string s = value as string;
bool b; if (bool.TryParse(s, out b))
{
return !b;
}
return false;
}
}
}
- 在LevelView.xaml文件,<UserControl>标签中,加入本地的命名空间:
xmlns:src="clr-namespace:MVVMTestApp.View"
- 在GRID布局前,将转换器类(src:BoolOpposite)的实例作为唯一标识(BoolOpposite)的资源, 在第二个LevelView 的CheckBox IsEnabled中,数据在绑定的View和data Model中传递时,调用该引用修改数据。
<UserControl.Resources>
<src:BoolOpposite x:Key="BoolOpposite"/>
</UserControl.Resources>
- 在LevelView的GRID布局中加入如下内容:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="Level" Text="{Binding Path=Name, Mode=OneWay}" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<CheckBox x:Name="Completed" IsChecked="{Binding Path=Completed, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Center" IsEnabled="{Binding Path=Completed, Converter={StaticResource BoolOpposite}}"/>
<TextBlock x:Name="Check" Text="{Binding Path=Completed, Mode=OneWay}" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
构建主页面
- 在MainPage.xaml文件,<Phone>标签中,增加View的命名空间
xmlns:views="clr-namespace:MVVMTestApp.View"
- 替换ContentPanel GRID内容如下:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Items Collected" Foreground="{StaticResource PhoneAccentBrush}" Style="{StaticResource PhoneTextLargeStyle}" />
<views:ItemView x:Name="ItemViewOnPage" Height="200"/> <TextBlock Text="Levels Completed" Foreground="{StaticResource PhoneAccentBrush}" Style="{StaticResource PhoneTextLargeStyle}" />
<views:LevelView x:Name="LevelViewOnPage" Height="200"/>
</StackPanel>
</Grid>
这样就把ItemView和LevelView两个视图跟应用的页面关联起来了。
- 视图有了,接下来就是要给视图填充数据了, 把MainPage.xaml.cs修改如下:
using System;
using System.Linq;
using System.Windows;
using Microsoft.Phone.Controls;
using MVVMTestApp.ViewModelNamespace; namespace MVVMTestApp
{
public partial class MainPage : PhoneApplicationPage
{
private ViewModel vm; // Constructor
public MainPage()
{
InitializeComponent();
vm = new ViewModel();
} protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e); // Later, you will replace this next line with something better.
vm.GetAccomplishments(); // There are two different views, but only one view model.
// So, use LINQ queries to populate the views. // Set the data context for the Item view.
ItemViewOnPage.DataContext = from Accomplishment in vm.Accomplishments where Accomplishment.Type == "Item" select Accomplishment; // Set the data context for the Level view.
LevelViewOnPage.DataContext = from Accomplishment in vm.Accomplishments where Accomplishment.Type == "Level" select Accomplishment; // If there is only one view, you could use the following code
// to populate the view.
//AccomplishmentViewOnPage.DataContext = vm.Accomplishments;
}
}
}
至此运行一下效果,内容已经填充到了主页面了
To be continue...
WP8 MVVM设计模式的更多相关文章
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- 浅谈 MVVM 设计模式在 Unity3D 中的设计与实施
初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...
- 设计模式笔记之三:Android DataBinding库(MVVM设计模式)
本博客转自郭霖公众号:http://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650236908&idx=1&sn=9e53 ...
- 通过TodoList案例对比Vue.js的MVVM设计模式与JQuery的MVP设计模式
Vue MVVM设计模式: 在使用vue进行编程时,不会再涉及到DOM的操作,取而代之的是修改数据层,当把数据进行变更的时候,vue之中它的底层会自动的根据数据的不同帮助我们去重新渲染页面. 编码时不 ...
- 使用MVVM设计模式构建WPF应用程序
使用MVVM设计模式构建WPF应用程序 本文是翻译大牛Josh Smith的文章,WPF Apps With The Model-View-ViewModel Design Pattern,译者水平有 ...
- Android DataBinding库(MVVM设计模式)
什么是MVVM 说到DataBinding,就有必要先提起MVVM设计模式.Model–View–ViewModel(MVVM) 是一个软件架构设计模式,相比MVVM,大家对MVC或MVP可能会更加熟 ...
- (一)mvc与mvvm设计模式
前沿:了解设计模式对我们而言,具有很大意义,对语言没有限制,它适用于任何语言,是一种变成思想.设计模式最初有四人帮提出,有兴趣的同学可以去了解下,今天给大家主要分析mvc与mvvm设计模式 一.mvc ...
- WPF系列教程——(二)使用Prism实现MVVM设计模式 - 简书
原文:WPF系列教程--(二)使用Prism实现MVVM设计模式 - 简书 本文假设你已经知道MVVM设计模式是什么,所以直接进入正题,今天我们就用Prism来实现WPF的MVVM设计模式,百度上关于 ...
- MVC和MVVM设计模式简单理解
1.mvc设计模式理解 Model: 模型 持有所有的数据状态和业务逻辑; 泛指数据库,链接数据库,建立数据模型 View: 视图 用来展示数据模型在页面上,泛指前端 Controller: 控制器, ...
随机推荐
- 解析6种常用View 的滑动方法
View 的滑动是Android 实现自定义控件的基础,实现View 滑动有很多种方法,在这里主要讲解6 种滑动方法,分别是layout().offsetLeftAndRight()与offsetTo ...
- python常用模块之shutil模块
python常用模块之shutil模块 shutil模块,高级的文件.文件夹.压缩包处理模块 1.shutil.copyfile(src,des[,length]):将文件内容拷贝到另一个文件 In ...
- linux下端口被占用
1.查看端口 netstat -ano 参数含义: -a, --all 显示监听或非监听状态的接口 Show both listening and non-listening (for TCP t ...
- 大规模向量相似度计算方法(Google在07年发表的文章)
转载请注明出处:http://www.cnblogs.com/zz-boy/p/3648878.html 更多精彩文章在:http://www.cnblogs.com/zz-boy/ 最近看了Goog ...
- BZOJ1101 POI2007 Zap 【莫比乌斯反演】
BZOJ1101 POI2007 Zap Description FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b, ...
- 异步任务中的重新进入(Reentrancy)
一个按钮,点击执行一个任务.我们可能直接在它的 Click 事件中写下了执行任务的代码. 一般我们无需担心这样的代码会出现什么问题——但是,这样的好事情只对同步任务有效:一旦进入了异步世界,这便是无尽 ...
- andriod studio报错 Emulator: emulator: ERROR: x86 emulation currently requires hardware acceleration! Emulator: Process finished with exit code 1
安装即可,再次运行svd,成功
- 《selenium2 python 自动化测试实战》(5)——键盘事件
键盘事件,就是键盘上的一些操作,比如Ctrl +C,Ctrl+V,Ctrl+X等. 对键盘的操作需要导入另一个键盘的库: from selenium.webdriver.common.keys imp ...
- 接口测试框架——第三篇:发送(requests)
把下面的代码放在requests_module.py文件中 # coding: utf-8 import requests import logging from requests.exception ...
- [Reship] Mean Shift 算法介绍
==================================================================================== This article ca ...