类似了Android里边的MVC模式, Windows Phone 有自己的Model-View-ViewModel模式,这种模式的作用就是为了Data和UI分离开来。

  如果你英文较好的话,你可以不再阅读以下内容,直接访问 WindowsPhone Dev Center学习阅读,因为以下内容是对其的一个中文复述。 

  

  这次演练,将执行以下的任务:

  1. 创建一个Model、一个ModelView和两个View;
  2. 使用XAML文件绑定数据;
  3. 创建一个定制数据的转换器;
  4. 保留页面的数据;
  5. 在isolated storage保存数据;
  6. 使用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设计模式的更多相关文章

  1. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  2. 浅谈 MVVM 设计模式在 Unity3D 中的设计与实施

    初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...

  3. 设计模式笔记之三:Android DataBinding库(MVVM设计模式)

    本博客转自郭霖公众号:http://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650236908&idx=1&sn=9e53 ...

  4. 通过TodoList案例对比Vue.js的MVVM设计模式与JQuery的MVP设计模式

    Vue MVVM设计模式: 在使用vue进行编程时,不会再涉及到DOM的操作,取而代之的是修改数据层,当把数据进行变更的时候,vue之中它的底层会自动的根据数据的不同帮助我们去重新渲染页面. 编码时不 ...

  5. 使用MVVM设计模式构建WPF应用程序

    使用MVVM设计模式构建WPF应用程序 本文是翻译大牛Josh Smith的文章,WPF Apps With The Model-View-ViewModel Design Pattern,译者水平有 ...

  6. Android DataBinding库(MVVM设计模式)

    什么是MVVM 说到DataBinding,就有必要先提起MVVM设计模式.Model–View–ViewModel(MVVM) 是一个软件架构设计模式,相比MVVM,大家对MVC或MVP可能会更加熟 ...

  7. (一)mvc与mvvm设计模式

    前沿:了解设计模式对我们而言,具有很大意义,对语言没有限制,它适用于任何语言,是一种变成思想.设计模式最初有四人帮提出,有兴趣的同学可以去了解下,今天给大家主要分析mvc与mvvm设计模式 一.mvc ...

  8. WPF系列教程——(二)使用Prism实现MVVM设计模式 - 简书

    原文:WPF系列教程--(二)使用Prism实现MVVM设计模式 - 简书 本文假设你已经知道MVVM设计模式是什么,所以直接进入正题,今天我们就用Prism来实现WPF的MVVM设计模式,百度上关于 ...

  9. MVC和MVVM设计模式简单理解

    1.mvc设计模式理解 Model: 模型 持有所有的数据状态和业务逻辑; 泛指数据库,链接数据库,建立数据模型 View: 视图 用来展示数据模型在页面上,泛指前端 Controller: 控制器, ...

随机推荐

  1. ffmpeg新老接口对比

    http://blog.csdn.net/leixiaohua1020/article/details/41013567

  2. Linux libusb 安装及简单使用

    Linux libusb 安装及简单使用 一.参考文档: . libusb1 fails do_configure task with “udev support requested but libu ...

  3. 启动和连接MySQL服务

    1.服务端启动 1.查看MySQL状态 sudo /etc/init.d/mysql status sudo /etc/init.d/mysql start | stop | restart sudo ...

  4. lx 与cd 的计算方法

    Candela to lux calculation with distance in meters The illuminance Ev in lux (lx) is equal to the lu ...

  5. HihoCoder1164 随机斐波那契(概率DP)

    描述 大家对斐波那契数列想必都很熟悉: a0 = 1, a1 = 1, ai = ai-1 + ai-2,(i > 1). 现在考虑如下生成的斐波那契数列: a0 = 1, ai = aj + ...

  6. ubuntu 安装nodejs/npm

    安装发行稳定版 Ubuntu 默认仓库里带有Node.js,版本较旧,这并不是最新版,但是应该很稳定.执行如下命令:   1 2 sudo apt-getupdate sudo apt-getinst ...

  7. JS实现浏览器打印、打印预览

    1.JS实现打印的方式方式一:window.print()window.print();会弹出打印对话框,打印的是window.document.body.innerHTML中的内容,下面是从网上摘到 ...

  8. POJ3422 Kaka's Matrix Travels 【费用流】*

    POJ3422 Kaka's Matrix Travels Description On an N × N chessboard with a non-negative number in each ...

  9. python笔记-19 javascript补充、web框架、django基础

    一.JavaScript的补充 1 正则表达式 1.1 test的使用 test 测试是否符合条件 返回true or false 1.2 exec的使用 exec 从字符串中截取匹配的字符 1.3 ...

  10. 用idea将javaweb项目部署到tomcat

    之前在网上找的一些web项目都是用eclipse开发的,想把这些项目导入到idea中,然后部署到tomcat中,在网上找了很多教程,很多都不靠谱,发现网上很多配置都是多余的,其实很多只需要按idea默 ...