wpf之mvvm

   初次接触的新名词--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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值