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: 控制器, ...
随机推荐
- ffmpeg新老接口对比
http://blog.csdn.net/leixiaohua1020/article/details/41013567
- Linux libusb 安装及简单使用
Linux libusb 安装及简单使用 一.参考文档: . libusb1 fails do_configure task with “udev support requested but libu ...
- 启动和连接MySQL服务
1.服务端启动 1.查看MySQL状态 sudo /etc/init.d/mysql status sudo /etc/init.d/mysql start | stop | restart sudo ...
- lx 与cd 的计算方法
Candela to lux calculation with distance in meters The illuminance Ev in lux (lx) is equal to the lu ...
- HihoCoder1164 随机斐波那契(概率DP)
描述 大家对斐波那契数列想必都很熟悉: a0 = 1, a1 = 1, ai = ai-1 + ai-2,(i > 1). 现在考虑如下生成的斐波那契数列: a0 = 1, ai = aj + ...
- ubuntu 安装nodejs/npm
安装发行稳定版 Ubuntu 默认仓库里带有Node.js,版本较旧,这并不是最新版,但是应该很稳定.执行如下命令: 1 2 sudo apt-getupdate sudo apt-getinst ...
- JS实现浏览器打印、打印预览
1.JS实现打印的方式方式一:window.print()window.print();会弹出打印对话框,打印的是window.document.body.innerHTML中的内容,下面是从网上摘到 ...
- POJ3422 Kaka's Matrix Travels 【费用流】*
POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...
- python笔记-19 javascript补充、web框架、django基础
一.JavaScript的补充 1 正则表达式 1.1 test的使用 test 测试是否符合条件 返回true or false 1.2 exec的使用 exec 从字符串中截取匹配的字符 1.3 ...
- 用idea将javaweb项目部署到tomcat
之前在网上找的一些web项目都是用eclipse开发的,想把这些项目导入到idea中,然后部署到tomcat中,在网上找了很多教程,很多都不靠谱,发现网上很多配置都是多余的,其实很多只需要按idea默 ...