wpf之mvvm

来源:互联网 发布:灵格斯 for mac 编辑:程序博客网 时间:2024/06/05 23:03

   初次接触的新名词--MVVM,听着好高大上的名字。经查阅,发现也没有想象中的那么难。

    mvvm【模型-视图-视图模型(Model-View-ViewModel)】是由MVP【模型-视图-表现类(Model-View-Presenter)】发展而来,MVP则是由MVC【模型-视图-控制器(ModelView Controller)】发展而来。由此看来,mvvm其实也不是新知识。

    View:是UI界面,就是用wpf的xaml实现的界面,负责与用户交互,接收用户输入,把数据展现给用户。

    ViewModel:一个C#类,负责收集需要绑定的数据和命令,实现View和Model之间的信息转换,处理UI逻辑。

    Model:就是系统中的对象,可包含属性和行为。

    mvvm示例

本次要做的Demo是计算两个数之和。

简单的界面如图所示:

Xaml代码:

<span style="font-family:KaiTi_GB2312;font-size:24px;"><Window x:Class="MVVM.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="350" Width="656">    <Grid Width="624"><TextBox Height="23" HorizontalAlignment="Left" Margin="41,90,0,0" Name="txtNum1" VerticalAlignment="Top" Width="120" Text="{Binding Num1}"/><TextBox Height="25" HorizontalAlignment="Left" Margin="195,88,0,0" Name="txtNum2" VerticalAlignment="Top" Width="120" Text="{Binding Num2}"/><Label Content="+" Height="28" HorizontalAlignment="Left" Margin="167,88,0,0" Name="lable1" VerticalAlignment="Top"/><TextBox Height="25" HorizontalAlignment="Left" Margin="364,88,0,0" Name="txtResult" VerticalAlignment="Top" Width="120" Text="{Binding Result}"/><Button  Content="=" Height="23" HorizontalAlignment="Left" Margin="328,90,0,0" Name="btnEqual" VerticalAlignment="Top" Width="28" Command="{Binding CaculateCommand}"/><Button Content="Clear" Height="26" HorizontalAlignment="Left" Margin="501,88,0,0" Name="btnClear" VerticalAlignment="Top" Width="45" Command="{Binding ClearCommand}"/>    </Grid></Window></span>

   此处代码的重点在于Binding,用绑定来实现和后台的交互。这样,若后台代码修改后,只要绑定的名称不变,就不会影响到界面。

Xaml的后台cs:

<span style="font-family:KaiTi_GB2312;font-size:24px;">/// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        //构造方法        public MainWindow()        {            InitializeComponent();            //将View的DataContext设为CaculatorViewModel实例            this.DataContext = new CaculatorViewModel();//ViewModel通过View类的DataContext属性绑定到View        }    }</span>
  View通过DataContext实现与ViewModel的交互。

Model层代码:

<span style="font-family:KaiTi_GB2312;font-size:24px;">//Model层的类    public class CaculatorModel    {        public int Num1 { get; set; }   //参数一        public int Num2 { get; set; }   //参数二        public int Result { get; set; } //计算结果    }</span>

重量级的部分马上呈现。

ICommand类型的基类,用来实现View和ViewModel之间Command的绑定。

<span style="font-family:KaiTi_GB2312;font-size:24px;">//ICommand类型的基类DelegateCommand    //目的是绑定命令属性。这个类的作用是实现了ICommand接口,WPF中实现了ICommand接口的类,才能作为命令绑定到UI。    public class DelegateCommand:ICommand    {        //        private Action<object> executeCommand;        public Action<object> ExecuteCommand        {            get { return executeCommand; }            set { executeCommand = value; }        }        //        private Func<object, bool> canExecuteCommand;        public Func<object, bool> CanExecuteCommand         {            get { return canExecuteCommand; }            set { canExecuteCommand = value; }        }        //        public event EventHandler CanExecuteChanged;        //是继承ICommand必须实现的方法,表示Command调用时判断是否能执行        public bool CanExecute(object parameter)        {            if (CanExecuteCommand!=null)            {                return this.CanExecuteCommand(parameter);            }            else            {                return true;            }        }        //是继承ICommand必须实现的方法,表示Command调用时具体执行逻辑        public void Execute(object parameter)        {            if (this.ExecuteCommand!=null)            {                this.ExecuteCommand(parameter);            }        }        public void RaiseCanExecuteChanged() {            if (CanExecuteCommand!=null)            {                CanExecuteChanged(this, EventArgs.Empty);            }        }        public DelegateCommand(Action<object> executeCommand, Func<object, bool> canExecuteCommand)         {            this.executeCommand = executeCommand;            this.canExecuteCommand = canExecuteCommand;        }    }</span>

ViewModel:

<span style="font-family:KaiTi_GB2312;font-size:24px;">//ViewModel的基类    public class ViewModelBase:INotifyPropertyChanged    {        //ViewModelBase实现了接口INotifyPropertyChanged, 在该接口中有一个PropertyChanged事件, 当ViewModel中的Property改变时,允许触发PropertyChanged事件,继而重新绑定数据到UI上。        //目的是绑定数据属性。这个类的作用是实现了INotifyPropertyChanged接口。WPF中类要实现这个接口,其属性成员才具备通知UI的能力        public event PropertyChangedEventHandler PropertyChanged;        public void RaisePropertyChanged(string propertyName)        {            if (this.PropertyChanged!=null)            {                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));            }        }    }</span>
所有的具体的ViewModel类都要继承ViewModel基类。

<span style="font-family:KaiTi_GB2312;font-size:24px;">//ViewModel具体的实现    public class CaculatorViewModel : ViewModelBase    {        #region Fields  字段        private int num1;        private int num2;        private int result;        private CaculatorModel model;        #endregion        #region Properties  属性        public int Num1        {            get { return num1; }            set            {                num1 = value;                this.RaisePropertyChanged("Num1");            }        }        public int Num2        {            get { return num2; }            set            {                num2 = value;                this.RaisePropertyChanged("Num2");            }        }        public int Result {            get { return result; }            set            {                result = value;                this.RaisePropertyChanged("Result");            }        }        #endregion        #region Commands  命令        public ICommand CaculateCommand { get; set; }        public ICommand ClearCommand { get; set; }        #endregion        #region Methods  方法        //相加的方法        public void Add(object param) {            Result = Num1 + Num2;        }        //清空的方法        public void Clear(object param) {            Result = 0;            Num1 = 0;            Num2 = 0;        }        //初始化Model数据        public void InitilizeModelData() {            var model = new CaculatorModel()            {                Num1 = 1,                Num2 = 1,                Result = 2            };            Num1 = model.Num1;            Num2 = model.Num2;            Result = model.Result;        }        //构造方法        public CaculatorViewModel() {            CaculateCommand = new DelegateCommand(Add, null);            //CaculateCommand = new DelegateCommand(Reduce, null);            ClearCommand = new DelegateCommand(Clear, null);            InitilizeModelData();        }        //相减的方法        //public void Reduce(object param)        //{        //    Result = Num1 - Num2;        //}        #endregion    }</span>
   若用户想将加法运算改为减法运算,我们只需要在ViewModel中添加一个减法运算的方法,在View中重新绑定一下就OK了。








0 0
原创粉丝点击