你的位置:首页 > ASP.net教程

[ASP.net教程]UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)


在做MVVM各种框架对比之前,我觉得有必要先自己做一个简单的MVVM实现案例比较好,这样就可以看到自己实现的时候有那些不方便的地方。而各种框架又是怎么解决我们这些麻烦的。

1、创建UWP空项目

1

将False改成True,这应该都懂的

2

2、构建项目结构

4

3、创建Binding基类

7

代码如下:

using System;using System.ComponentModel;using System.Runtime.CompilerServices;namespace MvvmDemo.Common{  /// <summary>  /// Viewmodel基类,属性双向绑定基础  /// </summary>  public class ViewModelBase : INotifyPropertyChanged  {    public event PropertyChangedEventHandler PropertyChanged;    /// <summary>    /// 属性变更通知    /// </summary>    /// <param name="propertyName">属性名</param>    public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")    {      if (PropertyChanged != null)      {        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));      }    }  }}

 

4、创建Command基类

代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Input;namespace MvvmDemo.Common{  public class DelegateCommand<T>: ICommand  {    /// <summary>    /// 命令    /// </summary>    private Action<T> _Command;    /// <summary>    /// 命令可否执行判断    /// </summary>    private Func<T, bool> _CanExecute;    /// <summary>    /// 可执行判断结束后通知命令执行    /// </summary>    public event EventHandler CanExecuteChanged;    /// <summary>    /// 构造函数    /// </summary>    /// <param name="command">命令</param>    public DelegateCommand(Action<T> command):this(command,null)    {    }    /// <summary>    /// 构造函数    /// </summary>    /// <param name="command">命令</param>    /// <param name="canexecute">命令可执行判断</param>    public DelegateCommand(Action<T> command,Func<T,bool> canexecute)    {      if(command==null)      {        throw new ArgumentException("command");      }      _Command = command;      _CanExecute = canexecute;    }    /// <summary>    /// 命令执行判断    /// </summary>    /// <param name="parameter">判断数据</param>    /// <returns>判定结果(True:可执行,False:不可执行)</returns>    public bool CanExecute(object parameter)    {      return _CanExecute == null ? true : _CanExecute((T)parameter);    }    /// <summary>    /// 执行命令    /// </summary>    /// <param name="parameter">参数</param>    public void Execute(object parameter)    {      _Command((T)parameter);    }  }}

5、创建ViewModel

代码如下:

using MvvmDemo.Common;using MvvmDemo.Models;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace MvvmDemo.ViewModels{  public class MainViewModel : ViewModelBase  {    private string _userId;    private string _userName;    private DelegateCommand<string> _loginCommand;        /// <summary>    /// 用户名    /// </summary>    public string UserId    {      get      {        return _userId;      }      set      {        _userId = value;        NotifyPropertyChanged();      }    }    /// <summary>    /// 用户名    /// </summary>    public string UserName    {      get      {        return _userName;      }      set      {        _userName = value;        NotifyPropertyChanged();      }    }    /// <summary>    /// 登陆命令    /// </summary>    public DelegateCommand<string> LoginCommand    {      get      {        return _loginCommand          ??(_loginCommand=new DelegateCommand<string>(            s=>            {              UserName = new UserModel().GetUserName(s);             },            s=>!string.IsNullOrEmpty(s)            ));      }    }  }}

6、创建View设置绑定

这里直接就拿MainView做例子,更改下布局

<Page  x:Class="MvvmDemo.MainPage"  ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  ="http://schemas.microsoft.com/winfx/2006/xaml"  ="using:MvvmDemo"  ="http://schemas.microsoft.com/expression/blend/2008"  ="http://schemas.open"  mc:Ignorable="d">  <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"      VerticalAlignment="Center"     HorizontalAlignment="Center">    <Grid.RowDefinitions>      <RowDefinition Height="50"/>      <RowDefinition Height="50"/>      <RowDefinition Height="50"/>    </Grid.RowDefinitions>    <Grid.ColumnDefinitions>      <ColumnDefinition Width="Auto" />      <ColumnDefinition Width="Auto" />    </Grid.ColumnDefinitions>    <TextBlock Text="用户ID:" Grid.Row="0" Grid.Column="0" Width="100" />    <TextBlock Text="用户名:" Grid.Row="1" Grid.Column="0" Width="100" />    <TextBox x:Name="txtUserID" Grid.Row="0" Grid.Column="1" Width="150" Text="{x:Bind VM.UserId,Mode=OneWay}" />    <TextBlock x:Name="txbUserName" Grid.Row="1" Grid.Column="1" Width="150" Text="{x:Bind VM.UserName,Mode=OneWay}" />    <Button x:Name="btnLogin" Content="Login" Grid.Row="2" Grid.ColumnSpan="2" Width="150" HorizontalAlignment="Center"        Command="{x:Bind VM.LoginCommand,Mode=OneWay}"        CommandParameter="{Binding Text,ElementName=txtUserID,Mode=OneWay}"/>  </Grid></Page>

后台添加代码

/// <summary>  /// 可用于自身或导航至 Frame 内部的空白页。  /// </summary>  public sealed partial class MainPage : Page  {    public MainViewModel VM =>new MainViewModel();    public MainPage()    {      this.InitializeComponent();      this.DataContext = VM;      }  }

 

7、创建Model

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace MvvmDemo.Models{  public class UserModel  {    public string GetUserName(string userid)    {      return string.Format("取得成功:{0}",userid);    }  }}

 

8、实行结果

输入内容前按钮自动不可用:

8

输入内容后按钮自动可用:

9

点击Login按钮:

10

9、总结

这种就是简单的登陆实现,涉及到了MVVM的View,Viewmodel,Model。这里按钮是自动判断是否可用,这个判断实现就在我们的Viewmodel。例子中涉及到了Xbind,这个和Binding是有区别的,具体说明下节在续。可见自己实现Mvvm模式也不是很难的事情,不过随着项目的复杂加深就会有很多问题,比如Viewmode之间通信等。