work hard work smart

专注于Java后端开发。 不断总结,举一反三。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

WPF 一个MVVM的简单例子

Posted on 2011-09-11 23:24  work hard work smart  阅读(23368)  评论(14编辑  收藏  举报

如下图是系统的结构图:这个示例是模仿计算器的MVVM模式的精简版,非常简单。

这篇文章就开门见山了,有关MVVM的理论部分,请参考MVVM设计模式

1、App中的代码:

        public App()
        {
            CalculatorView view = new CalculatorView();
            view.DataContext = new CalculatorViewModel();
            view.Show();
        }

2、Model层中CauculatorModel的代码

     class CauculatorModel
    {
         public string FirstOperand { get; set; }
         public string SecondOperand { get; set; }
         public string Operation { get; set; }
         public string Result { get; set; }
    }

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(this, new 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里传递的是一个参数,当然可以传递多个参数。

6、效果图:

参考资料:MVVM的一个Example