UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)

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

1、创建UWP空项目

UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)_第1张图片

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

2、构建项目结构

3、创建Binding基类

代码如下:

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"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MvvmDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    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、实行结果

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

UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)_第2张图片

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

点击Login按钮:

UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)_第3张图片

9、总结

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

你可能感兴趣的:(UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码))