wp8使用mvvm模式简单例子

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/37595445 m...
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/37595445

mvvm是silverlight/wpf下的mvc升华

通过一个简单的加法计算器例子来说明mvvm是什么

在设计界面完成设计之后,显示简单的布局,如下图:


然后来比较,传统的直接方式,mvc和mvvm三种的区别

1.最直接的方式无非就是双击Button按钮,在OnClick事件中获得两个TextBox的值,进行相加然后赋值给TextBlock

这样使得xaml.cs文件中直接操作了界面元素


2.mvc模式

首先定义一个AddModel类,并继承DependencyObject

public class AddModel:DependencyObject
    {


        public int Number1
        {
            get { return (int)GetValue(Number1Property); }
            set { SetValue(Number1Property, value); }
        }

        // Using a DependencyProperty as the backing store for Number1.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty Number1Property =
            DependencyProperty.Register("Number1", typeof(int), typeof(AddModel),null);



        public int Number2
        {
            get { return (int)GetValue(Number2Property); }
            set { SetValue(Number2Property, value); }
        }

        // Using a DependencyProperty as the backing store for Number2.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty Number2Property =
            DependencyProperty.Register("Number2", typeof(int), typeof(AddModel), null);



        public int Result
        {
            get { return (int)GetValue(ResultProperty); }
            set { SetValue(ResultProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Result.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ResultProperty =
            DependencyProperty.Register("Result", typeof(int), typeof(AddModel), null);

        
        
    }
继承了DependencyObject之后定义属性快捷方式如下:


定义好三个属性之后

在前台xaml文件引入命名空间

    xmlns:my="clr-namespace:PhoneApp1"

并在Resources中声明

    <phone:PhoneApplicationPage.Resources>
        <my:AddModel x:Key="addModel"></my:AddModel>
    </phone:PhoneApplicationPage.Resources>

将上面的几个控件的父容器,Grid的DataContext设置为addModel

并将各个控件的Text属性绑定对应的值,模式为双向绑定

<Grid x:Name="ContentPanel" Grid.Row="1"  DataContext="{StaticResource addModel}">
            <TextBox x:Name="txtNumber1" Text="{Binding Number1,Mode=TwoWay}" VerticalAlignment="Top" Width="129"/>
            <TextBox x:Name="txtNumber2" Text="{Binding Number2,Mode=TwoWay}" VerticalAlignment="Top" Width="129"/>
            <TextBlock  Text="+" VerticalAlignment="Top" RenderTransformOrigin="2.571,0.593"/>
            <Button Content="="  Click="Button_Click"/>
            <TextBlock x:Name="txtResult" Text="{Binding Result,Mode=TwoWay}" />

        </Grid>

为了方便看清楚各个控件Text的绑定情况遂删除了一些属性

在xaml.cs后台中,使用Button的OnClick事件

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            AddModel addModel = (AddModel) Resources["addModel"];
            addModel.Result = addModel.Number1 + addModel.Number2;
        }

获取到Resources中的addModel

并计算Result

启动运行


这样一来,在后台的xaml.cs中就没有操作界面元素了

但是还是要根据Button的OnClick事件才能实现

而在本例中mvvm模式的终极目标就是要消除OnClick!


3.mvvm模式

预备知识

Button有一个Command和CommandParameter属性

当Button的OnClick事件被触发时

Command属性对应的   继承了ICommand接口的类的Execute方法将会被执行,方法的参数是CommandParameter属性(Object类型)


于是需要一个新的类,叫做AddCommand,继承了ICommand接口

    public class AddCommand:ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            throw new NotImplementedException();
        }

        public event EventHandler CanExecuteChanged;
    }

并在AddModel中新增一个只读属性AddCmd

public ICommand AddCmd {
            get { return new AddCommand();} 
        }
返回xaml前台

在Button的属性中增加Command和CommandParameter属性的绑定

<Button Command="{Binding AddCmd}" CommandParameter="{Binding}" Content="=" HorizontalAlignment="Left" Margin="380,28,0,0" VerticalAlignment="Top"/>

(注意将OnClick事件清除)

启动运行


完成计算

这是后台中没有任何对前台界面元素的操作

mvvm完成




最后,思路有点乱

mvvm是靠一个继承了ICommand接口的类来实现的

当Button的OnClick事件被触发之后

Command属性对应的对象(这里为AddModel的AddCmd属性,该属性是只读的,返回一个AddCommand对象)的Execute方法会被执行

CommandParameter属性对应的值会被当做参数传入Execute方法(这里CommandParameter的值为AddModel本身)

在Execute方法中实现计算的操作

由于界面的控件数据源是双向绑定的

addModel的值一改变

界面就会显示出对应的值


那么这么做的好处是什么?

可以从代码中看到

前台的UI控件只要设置了数据源,并绑定了相应的属性就不需要进行任何操作了

在后台没有任务的业务逻辑处理的代码

所有的业务代码都在AddCommand的Execute方法中完成

而AddModel为UI控件的数据绑定提供了模型

相关文章
|
3月前
|
设计模式 前端开发 C#
WPF 项目中 MVVM模式 的简单例子说明
本文通过WPF项目中的加法操作示例,讲解了MVVM模式的结构和实现方法,包括数据模型、视图、视图模型的创建和数据绑定,以及命令的实现和事件通知机制。
|
6月前
|
Go 调度 Python
Django 视图探秘:FBV与CBV注册方式的异同,揭秘as_view()的执行魔法
Django 视图探秘:FBV与CBV注册方式的异同,揭秘as_view()的执行魔法
|
JavaScript 前端开发
【Vue指令】—v-if、v-show二者用法及区别
【Vue指令】—v-if、v-show二者用法及区别
|
JavaScript
Extjs中给一个组件命名时,id,name,hiddenName这三者的用法和区别是什么
Extjs中给一个组件命名时,id,name,hiddenName这三者的用法和区别是什么
|
前端开发
前端学习笔记202306学习笔记第三十七天-js-组合继承1
前端学习笔记202306学习笔记第三十七天-js-组合继承1
116 0
|
设计模式 缓存 JavaScript
也玩MVC3.“.NET研究”0 Razor自定义视图引擎来修改默认的Views目录结构
刚刚爱上MVC3.0,几个不眠夜的学习越来越有趣。今天随手尝试自定义Mvc3.0的视图引擎,虽然已成功,但是还发现有点小疑问。随手贴出来希望大家指教指教。 MVC的视图文件目录被固定/Views目录内,区域视图文件也是被固定在/Areas目录下,出于好奇和对目录名的敏感,尝试修改它。
908 0
|
前端开发 C#
WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码)
原文:WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码)   之前的改进已经挺棒的,但是我们现在知道了后台代码的问题,那是否可能把后台代码全部去除呢?这时候就该WPF binding 和 commands 来做的事情了。
1174 0
|
前端开发 C# 开发者
WPF MVVM 架构 Step By Step(2)(简单的三层架构示例及粘合代码GLUE code)
原文:WPF MVVM 架构 Step By Step(2)(简单的三层架构示例及粘合代码GLUE code)      我们第一步就是去了解三层架构和问题然后去看MVVM是怎么去解决这些问题的。      现在,感觉和事实是完全不同的两个东西。
1502 0
|
前端开发 C# 开发者
WPF MVVM 架构 Step By Step(3)(把后台代码移到一个类中)
原文:WPF MVVM 架构 Step By Step(3)(把后台代码移到一个类中)   我觉得大部分开发者应该已经知道怎么去解决这个问题。一般都是把后台代码(GLUE code)移动到一个类库。这个类库用来代表UI的属性和行为。
1056 0