zoukankan      html  css  js  c++  java
  • wp8使用mvvm模式简单例子

    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控件的数据绑定提供了模型

  • 相关阅读:
    伪元素:placeholder-shown&&:focus-within
    伪元素:target
    伪元素:focus-within
    MpVue解析
    ESLint在vue中的使用
    vue动态 设置类名
    Java 文件流操作.
    SpringMVC 与 REST.
    基于Nginx和Zookeeper实现Dubbo的分布式服务
    基于Spring的RPC通讯模型.
  • 原文地址:https://www.cnblogs.com/jchubby/p/4429742.html
Copyright © 2011-2022 走看看