Model View View-Model 模式(MVVM)

MVVM是wp7开发的一种设计模式,其目的也是为了将数据层(Model)与UI层(View)分开。ViewModel则是用来连接数据层与UI层的C#类。个人感觉,MVVM和MVC是差不多的。下面就用微软的sample code来理解下MVVM 设计模式。

 

这个例子是一个游戏成就的记录工具,分为两个部分:收集品成就,以及等级成就。

收集品成就 又分为药品数量,硬币数量,心数量。

等级成就 有1,2,3三个等级。

 

游戏效果如下

 

游戏效果

 

下面讲实现代码,先建立一个Silverlight for Windows Phone工程。

solution结构如下

 

solution

 

 建立Model层类

 

建立ViewModel层类

 

 建立两个新View,ItemView.xaml(收集品的表示区域)和LevelView.xaml(等级的表示区域)

 编辑ItemView.xaml,在GRID element里添加以下source

 

 

建立第二个view

在头部的UserControl增加以下代码。这里表示要引用MVVMTestApp.View的source。这里:src是自定义的tag名,也可以用别的命名。

下面调用BoolOpposite的时候要跟前缀src:。

xmlns:src="clr-namespace:MVVMTestApp.View"

 

在UserControl 和 GRID 之间, 增加以下代码,这里添加source的目的是增加一个Converter。

因为开发者认为等级成就完成后,是不能退回去的。也就是说当等级成就为false时,该等级是可编辑的。

但等级变成true以后就不能再编辑了。

 

<UserControl.Resources>
    <src:BoolOpposite x:Key="BoolOpposite"/>
</UserControl.Resources>

 

GRID element里添加以下source

 

 

这里,CheckBox是否钩上,以及能否编辑都与Completed属性绑定,但是能否编辑增加了反转Completed属性的Converter:BoolOpposite

<CheckBox x:Name="Completed" IsChecked="{Binding Path=Completed, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Center" IsEnabled="{Binding Path=Completed, Converter={StaticResource BoolOpposite}}"/>

 

将第二个View里,UI层的对应代码替换如下:

 

编辑主View,在phone tag里添加一下代码:

xmlns:views="clr-namespace:MVVMTestApp.View"

ContentPanel GRID element里,增加以下属性

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>

替换ContentPanel GRID element 的默认代码如下

 <!--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>
修改主View对应的UI层代码
 
增加一个类用以维护页面的状态。
 
修改App.xaml对应的Code,替换如下
 
 主View 的对应Code,替换如下: 
     
     
// Old instance of the application
// The user started the application from the Back button.
if (!StateUtilities.IsLaunching && this.State.ContainsKey("Accomplishments"))
{
    vm = (ViewModel)this.State["Accomplishments"];
    //MessageBox.Show("Got data from state");
}
// New instance of the application
// The user started the application from the application list,
// or there is no saved state available.
else
{
    vm.GetAccomplishments();
    //MessageBox.Show("Did not get data from state");
}
OnNavigatedTo 函数后增加以下方法,当State里没有Accomplishments属性时,增添Accomplishments属性,否则替换它。
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    if (this.State.ContainsKey("Accomplishments"))
    {
        this.State["Accomplishments"] = vm;
    }
    else
    {
        this.State.Add("Accomplishments", vm);
    }

  
增加application bar, OnNavigatedFrom method后面添加一下代码
private void AppBarSave_Click(object sender, EventArgs e)
{
    vm.SaveAccomplishments();
}
在MainPage.xaml 里,把</phone:PhoneApplicationPage.ApplicationBar>-->替换如下:
<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" >
        <shell:ApplicationBarIconButton IconUri="AppBarSave.png" Text="Save"  Click="AppBarSave_Click" />
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
完成!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值