zoukankan      html  css  js  c++  java
  • [Silverlight]MVVM+MEF框架Jounce练习(1)

    光学不练,对一些概念的理解就只能停留在表面了。这个系列主要记录自己对Jounce框架的理解和测试代码,以加深对MVVM和Silverlight的一些概念的理解。本例主要测试Jounce框架中View和ViewModel的通信。

    MVVM的优点

    我认为Model、View和ViewModel的设计原则:模型、视图和视图模型分离,主要有两方面的优点:

    1. 便于团队协作和单元测试。开发人员开发出适合业务逻辑的Model和ViewModel,并在没有View的情况下就可以做单元测试;美工人员根据ViewModel设计好View;测试人员可以只根据View、ViewModel或者Model其中之一的情况下写测试代码。还实现了更好的模块化,尽管有时我们都是一个人在做这些事情。

    2.XAML系的特点,采用MVVM的模式,可以减少很多繁琐的界面更新的代码,例如对象属性改变后,在ViewModel中调用适当的方法,就可以完成界面的更新,这样我们可以更多的关心业务逻辑。相对于传统的Winforms,更适合采用这种设计模式。

    思维方式的改变

    我以前直接在View的后台代码里,想怎么控制界面都可以。现在MVVM了,给我整分离了,ViewModel和View不能相互引用对方,两者如何通讯呢?例如我点击Save按钮,想要显示一个等待界面给用户:以前多方便,直接调用一个等待界面代码即可。现在呢?点击事件抽象成Command,绑定由ViewModel来处理,而ViewModel不能引用View,又如何改变View的状态呢?Jounce又是如何做到的呢?我们想达到的是这种效果:

    可以有两种方法:

    1. 利用View和ViewModel的契约

    这种契约其实就是绑定,View界面元素的属性绑定到ViewModel的属性上,这样就形成了一种约定:ViewModel的属性会影响元素显示,反过来也一样(如果是双向绑定)。

    View代码可以这样写:

    <Grid x:Name="LayoutRoot" Background="White">
            <StackPanel x:Name="Sp">
                <TextBlock FontSize="36" Text="{Binding Welcome}"/>
                <Button Width="100" Margin="4" Content="Save" Command="{Binding SaveCommand}"/>
            </StackPanel>
            <TextBlock Text="正在保存..." Visibility="{Binding IsSaving}" Foreground="Blue" Height="50" x:Name="tbSaving" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>

    ViewModel这样写:

    [ExportAsViewModel(typeof (MainViewModel))]
        public class MainViewModel : BaseViewModel
        {
            public MainViewModel()
            {
                SaveCommand = new ActionCommand<object>(o =>
                {
                    IsSaving = Visibility.Visible;
                });
            }
    
            public string Welcome
            {
                get { return InDesigner ? "Jounce Design-time View" : "Welcome to Jounce."; }
            }
    
            public IActionCommand<object> SaveCommand { get; set; }
    
            Visibility _isSaving=Visibility.Collapsed;
            public Visibility IsSaving
            {
                get
                {
                    return _isSaving;
                }
                set
                {
                    _isSaving = value;
                    RaisePropertyChanged("IsSaving");
                }
            }
        }

    Jounce的BaseViewModel实现了INotifyPropertyChanged接口,通过调用RaisePropertyChanged方法可以在属性改变时,通知界面更新。

    为了简单,这里实现的很简陋,比较优雅的实现可以使用BusyIndicator控件。

    2.利用Jounce的GoToVisualState

     Jounce的BaseViewModel提供了GoToVisualState方法,可以在不引用View的情况下改变View的状态。

    View代码:

    <Grid x:Name="LayoutRoot" Background="White">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="Commstates">
                    <VisualState x:Name="Normal"/>
                    <VisualState x:Name="Saving">
                        <Storyboard>
                            <DoubleAnimation Duration="0" Storyboard.TargetName="tbSaving" Storyboard.TargetProperty="Opacity" To="1"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <StackPanel x:Name="Sp">
                <TextBlock FontSize="24" Text="{Binding Welcome}"/>
                <Button Width="100" Margin="4" Content="Save" Command="{Binding SaveCommand}"/>
            </StackPanel>
            <TextBlock Text="正在保存..." Foreground="Blue" Height="50" x:Name="tbSaving" Opacity="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>

    ViewModel代码:

    public MainViewModel()
    {
         SaveCommand = new ActionCommand<object>(o =>{
               GoToVisualState("Saving", true);
          }); 
    }

    参考:

    [Silverlight]MVVM+MEF框架Jounce学习(2):标记和绑定

    更深刻的理解Jounce,可以参考Jounce的源代码。

  • 相关阅读:
    将1、2、3、……、n这n个连续自然数分成g组,使每组的和相等。g组中个数最多的一组有几个?
    磁带机、驱动器、磁带库、机械手之间的区别
    Mysql基础命令
    pip 加速下载
    NBU命令之 nbftconfig :配置与光纤传输 (FT) 服务器和 SAN 客户端相关的属性
    IEDriverServer.exe驱动问题汇总
    系统集成项目管理工程师考试2020介绍
    LTO1,LTO2,LTO3,LTO4,LTO5 LTO6 磁带读写速度和兼容性及LTO6主要参数
    Mysql 备份方式 MySQL Agent & MySQL Enterprise Backup & Percona XtraBackup
    Netbackuk命令之bpclntcmd
  • 原文地址:https://www.cnblogs.com/slmk/p/2797009.html
Copyright © 2011-2022 走看看