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: 控制器, ...
随机推荐
- SQL映射文件
SQL映射文件的几个顶级元素 mapper - namespace cache - 配置给定命名空间的缓存 cache-ref – 从其他命名空间引用缓存配置 resultMap –用来描述数据库结 ...
- jauery-layer弹出框的使用
一布局: <div id="detailLayer"> <div class="box-header"> <div class=& ...
- ubuntu16扩展屏设置
new ubuntu system setting - Expansion screen settings. 1,System Settings–>Displays 1,set big scre ...
- paddlepaddle初步印象
从其官网整理了一些资料如下: 1.基本概念 基本使用概念 PaddlePaddle是源于百度的一个深度学习平台.PaddlePaddle为深度学习研究人员提供了丰富的API,可以轻松地完成神经网络配置 ...
- 创建你的第一个Flutter应用程序
前言 Flutter,Google推出的跨平台开发框架.就在前几天,Flutter的首个发布预览版(Release Preview 1)正式发布! 即将迎来Flutter 正式版(1.0).本篇将带你 ...
- oracle 未明确定义错误
select sysuser1.* from (select sysuser2.*, rownum rownum_temp from (select yycgdmx.id yycgdmxid, -- ...
- MPI 学习
一.编译MPI mpic++ test.cc -o test 二.启动MPI mpiexec -np 10 ./test 三.几个例子 第一个进程向第二个发一个数,第二个进程向第三个进程发送一个数.. ...
- Form元素与字体
前言 以前写代码的时候总是喜欢在body元素中写字体属性,用以控制全局字体样式,后来发现表单元素中的字体样式并不能被控制,郁闷的不行. 解决方法 因为表单元素无法继承body的字体属性,所以要单独设置 ...
- IE中拖放问题
1.所有的元素上都能绑定放置目标的事件,但并不保证此元素是有效的放置对象. 默认情况下,IE中只有文本框(<input/>或<textarea/>)是网页上唯一有效的放置目标. ...
- Objective-C的属性和成员变量用法及关系浅析
在使用Objective-C语言进行了一段时间的iOS开发之后,发现自己的语言基础相对薄弱,于是开始弥补自己的短处.我发现在用过一种语言之后,再回过头来看它的很多原理会发现有更加深刻的理解.下面就对一 ...