zoukankan      html  css  js  c++  java
  • MVVM MVC

    在WPF的MVVM模式中,View和ViewModel之间数据和命令的关联都是通过绑定实现的,绑定后View和ViewModel并不产生直接的依赖。具体就是View中出现数据变化时会尝试修改绑定的目标。同样View执行命令时也会去寻找绑定的Command并执行。反过来,ViewModel在Property发生改变时会发个通知说“名字叫XXX的Property改变了,你们这些View中谁绑定了XXX也要跟着变啊!”,至于有没有View收到是不是做出变化也不关心。ViewModel中的Command脱离View就更简单了,因为Command在执行操作过程中操作数据时,根本不需要操作View中的数据,只需要操作ViewModel中的Property就可以了,Property的变化通过绑定就可以反映到View上。这样在测试Command时也不需要View的参与。这也是我在接触WPF初期时根本理解不了的所谓数据驱动。

    这样一来ViewMode可以在完全没有View的情况下测试,View也可以在完全没有ViewModel的情况下测试(当然只是测试界面布局和动画等业务无关的内容)。

    1、App中的代码:

    public App()

    {

        CalculatorView view = new CalculatorView();

        view.DataContext = new CalculatorViewModel();

        view.Show();

    }

    2、Model层中CauculatorModel的代码

    class CauculatorModel

    {

         public string FirstOperand { getset; }

         public string SecondOperand { getset; }

         public string Operation { getset; }

         public string Result { getset; }

    }

    3、Command

    public class DeletgateCommand<T>:ICommand

     {

         private readonly Action<T> _executeMethod = null;

         private readonly Func<T,bool> _canExecuteMethod = null;

         public DeletgateCommand(Action<T> executeMethod)

             this(executeMethod, null)

         { }

         public DeletgateCommand(Action<T> executeMethod, Func<T,bool> canExecuteMethod) 

         {

             if (executeMethod == null)

                 throw new ArgumentNullException("executeMetnod");

             _executeMethod = executeMethod;

             _canExecuteMethod = canExecuteMethod;

         }

         #region ICommand 成员

         /// <summary>

         ///  Method to determine if the command can be executed

         /// </summary>

         public bool CanExecute(T parameter)

         {

             if (_canExecuteMethod != null)

             {

                 return _canExecuteMethod(parameter);

             }

             return true;

         }

         /// <summary>

         ///  Execution of the command

         /// </summary>

         public void Execute(T parameter)

         {

             if (_executeMethod != null)

             {

                 _executeMethod(parameter);

             }

         }

         #endregion

         event EventHandler ICommand.CanExecuteChanged

         {

             add { CommandManager.RequerySuggested += value; }

             remove { CommandManager.RequerySuggested -= value; }

         }

         #region ICommand 成员

         public bool CanExecute(object parameter)

         {

             if (parameter == null && typeof(T).IsValueType)

             {

                 return (_canExecuteMethod == null);

             }

              

             return CanExecute((T)parameter);

         }

         public void Execute(object parameter)

         {

             Execute((T)parameter);

         }

         #endregion

     }

    4、ViewModwl层,为了简化,此处Add方法采用硬编码的形式

    public class CalculatorViewModel

     {

         CauculatorModel calculatorModel;

         private DeletgateCommand<string> addCommand;

          

         public CalculatorViewModel()

         {

             calculatorModel = new CauculatorModel();

         }

         #region Public Properties

         public string FirstOperand

         {

             get {  return calculatorModel.FirstOperand;  }

             set { calculatorModel.FirstOperand = value;  }

         }

         public string SecondOperand

         {

             get return calculatorModel.SecondOperand; }

             set { calculatorModel.SecondOperand = value; }

         }

         public string Operation

         {

             get return calculatorModel.Operation; }

             set { calculatorModel.Operation = value; }

         }

         public string Result

         {

             get return calculatorModel.Result; }

             set { calculatorModel.Result = value; }

         }

         #endregion

         public ICommand AddCommand

         {

             get

             {

                 if (addCommand == null)

                 {

                     addCommand = new DeletgateCommand<string>(Add, CanAdd);

                 }

                 return addCommand;

             }

         }

             

         public  void Add(string x)

         {

             FirstOperand = x;

             SecondOperand = x;

             Result = (double.Parse(FirstOperand) + double.Parse(SecondOperand)).ToString();

             Operation = "+";

             MessageBox.Show( FirstOperand+ Operation +SecondOperand +"=" + Result);

         }

         private static bool CanAdd(string num)

         {

             return true;

         }

     }

    ViewModelBase中的代码:

    public abstract class ViewModelBase : INotifyPropertyChanged

     {

         public event PropertyChangedEventHandler PropertyChanged;

         protected void OnPropertyChanged(string propertyName)

         {

             PropertyChangedEventHandler handler = PropertyChanged;

             if (handler != null)

             {

                 handler(thisnew PropertyChangedEventArgs(propertyName));

             }

         }

     }

     5、View层

    <Grid>   

           <TextBox  Height="23" Margin="12,63,0,0" Name="textBox1" VerticalAlignment="Top" HorizontalAlignment="Left"  Width="120" />

           <Label Margin="12,25,95,0" Name="label2" Height="32" VerticalAlignment="Top">请输入x的值! x+x=? </Label>

           <Button Height="23" Command="{Binding AddCommand}"  

                   CommandParameter="{Binding ElementName=textBox1,Path=Text}"   HorizontalAlignment="Left" Margin="12,102,0,0" Name="button1" VerticalAlignment="Top" Width="75">

               确定</Button>

       </Grid>

     CommandParameter里传递的是一个参数,当然可以传递多个参数。

  • 相关阅读:
    继承
    对象与类
    反射
    I/O流
    字符串
    Map的entrySet()方法
    接口与内部类
    Git Usage Summary
    HTML(5)
    毕业设计:下载
  • 原文地址:https://www.cnblogs.com/gaoxianzhi/p/11941390.html
Copyright © 2011-2022 走看看