UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)
在做MVVM各种框架对比之前,我觉得有必要先自己做一个简单的MVVM实现案例比较好,这样就可以看到自己实现的时候有那些不方便的地方。而各种框架又是怎么解决我们这些麻烦的。
案例介绍:用户登录画面,没有输入用户ID数据时按钮不可用,输入用户ID数据后按钮可以使用。点击按钮获取用户名信息。
案例下载:https://github.com/NewBLife/UWP/tree/master/MvvmDemo
1、创建UWP空项目

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

2、构建项目结构
按照MVVM模式思想,一般都会包含Views,ViewModels,Models,如果项目比较复杂在ViewModel和Model之间还会有Service层。

复杂系统情况:


3、创建Binding基类
MVVM核心技能之一:绑定。如果是单向显示数据的话直接使用类属性就可以,如果想交互双向绑定的实现INotifyPropertyChanged接口。其中的PropertyChanged事件会通知UI改变绑定值状态。

代码如下:
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基类
MVVM核心技能二:ICommand。这个的存在使我们的UI逻辑可以搬迁到其他地方处理,给自动化单体测试与分工设计带来了可能。按钮的Click事件,Combox选择,列表选择等等都可以使用Command形式绑定到ViewModel的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
脱离UI的数据处理中心。让我们可以单独编写它的测试程序来完成UI测试。主要目的就是将DB数据整合为用户想看的数据。
代码如下:
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设置绑定
绑定6.0后有X:Bind,之前有Binding。x:Bind是编译时确定绑定对象,Binding是实行时确定绑定对象。总得来说X:Bind的速度比Binding快,在程序运行前就能发现绑定错误的问题。
这里直接就拿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=""/>
<RowDefinition Height=""/>
<RowDefinition Height=""/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> <TextBlock Text="用户ID:" Grid.Row="" Grid.Column="" Width="" />
<TextBlock Text="用户名:" Grid.Row="" Grid.Column="" Width="" />
<TextBox x:Name="txtUserID" Grid.Row="" Grid.Column="" Width="" Text="{x:Bind VM.UserId,Mode=OneWay}" />
<TextBlock x:Name="txbUserName" Grid.Row="" Grid.Column="" Width="" Text="{x:Bind VM.UserName,Mode=OneWay}" />
<Button x:Name="btnLogin" Content="Login" Grid.Row="" Grid.ColumnSpan="" Width="" 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
由于这里没有复杂逻辑,就不添加Service了。
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、实行结果
输入内容前按钮自动不可用:

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

点击Login按钮:

9、总结
这种就是简单的登陆实现,涉及到了MVVM的View,Viewmodel,Model,以及XBind的用法。6.0后有X:Bind,之前有Binding。x:Bind是编译时确定绑定对象,Binding是实行时确定绑定对象。总得来说X:Bind的速度比Binding快,在程序运行前就能发现绑定错误的问题。登陆页面的按钮是随着输入自动判断是否可用,这个就是Icommand一个方法Canexcute的作用。可见自己实现Mvvm模式也不是很难的事情,不过随着项目的复杂加深就会有很多问题,比如Viewmode之间通信等,这个时候才是MVVM框架的优势所在。
UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)的更多相关文章
- UWP开发之Mvvmlight实践七:如何查找设备(Mobile模拟器、实体手机、PC)中应用的Log等文件
在开发中或者后期测试乃至最后交付使用的时候,如果应用出问题了我们一般的做法就是查看Log文件.上章也提到了查看Log文件,这章重点讲解下如何查看Log文件?如何找到我们需要的Packages安装包目录 ...
- UWP开发之Mvvmlight实践一:如何在项目中添加使用Mvvmlight(图文详解)
最近一直在做UWP开发,为了节省成本等等接触到MVVMlight,觉得有必要发点时间研究它的用法与实现原理才行.如果有问题的地方或者有好的建议欢迎提出来. 随着移动开发的热门,Mvvmlight在An ...
- UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享
在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎 ...
- UWP开发之Mvvmlight实践二:Mvvmlight的核心框架MVVM与MVC、MVP的区别(图文详解)
最近UWP开发在海外很潮流,随着微软收购Xamarin,我们这些C#程序员也可以靠这杆小米枪挑战Android,IOS平台了. 那我们为什么选择MVVM做UWP开发?MVC,MVP,MVVM他们之间到 ...
- UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理
最近比较忙有一段时间没有更新了,再接再厉继续分享. 案例下载:https://github.com/NewBLife/UWP/tree/master/SuspendSample 先我们看看App在生命 ...
- UWP开发之Mvvmlight实践八:为什么事件注销处理要写在OnNavigatingFrom中
前一段开发UWP应用的时候因为系统返回按钮事件(SystemNavigationManager.GetForCurrentView().BackRequested)浪费了不少时间.现象就是在手机版的详 ...
- UWP开发之Mvvmlight实践四:{x:bind}和{Binding}区别详解
{x:bind}是随着UWP被推出而被添加的,可以说是Win10 UWP开发专有扩展.虽然 {x:Bind} 缺少{Binding} 中的一些功能,但它运行时所花费的时间和使用的内存量均比 {Bind ...
- UWP开发之Mvvmlight实践六:MissingMetadataException解决办法(.Net Native下Default.rd.xml配置问题)
最近完成一款UWP应用,在手机端测试发布版(Release)的时候应用莫名奇妙的强行关闭,而同样的应用包在PC端一点问题都没有,而且Debug版在两个平台都没有问题,唯独手机的Release版有问题. ...
- UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)
前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...
随机推荐
- 用SQL语句将数据表中的数据保存为JSON格式
没有找到好的工具,只想到了拼字符串的方式,用 NVARCHAR(MAX) 可能有截断,不推荐使用,方法中使用了 FOR XML PATH('') 实现,有关其使用方法参考这里 表结构: SQL ...
- [转]android:动态创建多个按钮 及 批量设置监听
之前投机取巧,先创建好多个按钮,再根据需要的数量进行部分隐藏,不过还是逃不过呀. 这样根本无法批量地 findId,批量地 设置监听. 所以今天还是认认真真地研究回“动态创建按钮”,终于,通过不断尝试 ...
- ajax的理解与工作流程
一.什么是ajax ajax是一种异步通信技术.在ajax出现之前,客户端与服务端之间直接通信.引入ajax之后,客户端与服务端加了一个第三者--ajax.有了ajax之后,通过在后台与服务器进行少量 ...
- SQL执行效率2-执行计划
以下语句可以进行SQL 语句执行时间分析,两个Go之间就是SQL查询语句 use Work--数据库名 go set statistics profile on set statistics io o ...
- PHP基础知识之foreach
定义: foreach (array_expression as $value)------------循环时传递key foreach (array_expression as $key => ...
- 使用EF取数据库返回的数据
目录 一.取oracle自定义函数返回的自定义类型. 一.取oracle自定义函数返回的自定义类型. 1.首先创建一个函数返回自定义类型集合 --1.建立自定义类型 CREATE OR REPLACE ...
- ASP.NET MVC 路由(四)
ASP.NET MVC路由(四) 前言 在前面的篇幅中我们讲解路由系统在MVC中的运行过程以及粗略的原理,想必看过前面篇幅的朋友应该对路由有个概念性的了解了,本篇来讲解区域,在读完本篇后不会肯定的让你 ...
- CoreProfiler/NanoProfiler性能调试监控系列总目录
NanoProfiler - 适合生产环境的性能监控类库 之 基本功能篇 NanoProfiler - 适合生产环境的性能监控类库 之 大数据篇 NanoProfiler - 适合生产环境的性能监控类 ...
- 修改注册表 去除Windows快捷方式图标小箭头
一些朋友不喜欢Windows系统中快捷方式图标上面的小箭头,下面介绍如何修改注册表去除快捷方式图标上的小箭头. 1.开始->运行->输入regedit,启动注册表编辑器,然后; 2.依次展 ...
- Java中instanceof和isInstance区别详解
一次性搞定instanceof和isInstance,instanceof和isInstance长的非常像,用法也很类似,先看看这两个的用法: obj.instanceof(class) 也就是说这 ...