title author date CreateTime categories
win10 uwp 轻量级 MVVM 框架入门 2.1.5.3199
lindexi
2019-11-29 10:16:11 +0800
2018-6-10 17:45:4 +0800
Win10 UWP mvvm

一个好的框架是不需要写教程大家看到就会用,但是本金鱼没有那么好的技术,所以需要写很长的博客告诉大家如何使用我的框架。

在本文开始之前,希望大家是有 UWP 基础而且熟悉 C#,因为本金鱼有很多认为是大家都知道的就没有在博客说。

安装

首先需要从 Nuget 安装两个库

  • lindexi.uwp.Framework

  • lindexi.MVVM.Framework

第一个库是使用 UWP 的封装,因为我还有 WPF 的封装,实际上在使用,用 WPF 或 UWP 是差不多的。只要存在 UWP 和 WPF 不相同的库,我就把这写封装在不同的库。

使用 WPF 项目只需要安装 lindexi.wpf.Framework 这个库。因为 Nuget 可以找到依赖库,所以只需要安装 lindexi.wpf.Framework 就会自动安装 lindexi.MVVM.Framework 。如果现在使用的是 Xarmain ,那么安装 lindexi.MVVM.Framework 就可以,这个库使用 dotnet framework 4.5 和 dotnet standard 2.0 ,所以在很多项目都可以使用。

项目要求

安装这个库的要求是 UWP 的最低版本是 16299 ,因为在 16299 才支持 dotnet standard 2.0,在之前的版本是不支持。

如果使用的是 WPF 项目,要求项目最低版本是 dotnet framework 4.5

主界面

这个框架是适合有一个主界面和多个子页面的程序,而且适合多个子页面之间有通信,包括子页面让另一个页面跳转等的框架。

先创建一个 ViewModel 类,表示这是主界面。

    public class ViewModel : NavigateViewModel

然后在 MainPage 添加 ViewModel ,因为需要做导航,所以需要在前台添加 Frame 用来做导航。

    <Grid>
<Frame x:Name="Frame" />
</Grid>
        public ViewModel.ViewModel ViewModel { get; set; } = new ViewModel.ViewModel();

不需要我说,大家也知道代码放在哪

很多程序在启动的是否都需要读取配置,这时就需要先显示一个初始页面,在这个页面显示的过程,加载很多数据

在 Main 构造函数使用 LoadAsync 方法,这个方法先跳转到 SplashPage 然后再调用 ViewModel 的读取数据

        public MainPage()
{
this.InitializeComponent();
LoadAsync();
}

在 LoadAsync 方法使用 ViewModel.Read 读取数据,而且组合对应的启动的页面和 ViewModel 。这里还写有两个页面 MeetokaCutusaiPage 和 WastounowMearhallworcelPage ,使用下面代码组合

        private async void LoadAsync()
{
Frame.Navigate(typeof(SplashPage));
await ViewModel.Read(); var viewModelPage = new List<ViewModelPage>()
{
new ViewModelPage(new NavigatableViewModel<WastounowMearhallworcelModel>(),new NavigatablePage(typeof(WastounowMearhallworcelPage))),
new ViewModelPage(new NavigatableViewModel<MeetokaCutusaiModel>(),
new NavigatablePage(typeof(MeetokaCutusaiPage)))
};
ViewModel.ViewModelPage = viewModelPage;
ViewModel.NavigatedTo(this, (NavigateFrame)Frame);
}

这里创建 ViewModelPage 需要 INavigatableViewModel 和 INavigatablePage 的原因是,我这个还有在 WPF 使用,大家都知道 WPF 的 Frame 跳转和 UWP 的相同,所以需要传入不同的类

这里大家还看到我使用了(NavigateFrame)Frame,因为在 ViewModel.NavigatedTo 使用的是 INavigateFrame 来作为跳转,如果传入其他的参数就需要自己写的 ViewModel 进行处理。

这个方式是代码进行组合多个页面和 ViewModel ,如果页面和 ViewModel 比较少,使用这个方法还是可以。如果页面比较多,那么就建议使用反射或其他方法组合,不要自己写。

读取文件

在软件启动的过程,需要先使用 ViewModel 读取配置信息,读取到的配置信息放在 ViewModel 的属性,在页面跳转,ViewModel 可以把信息传给跳转的 ViewModel 这样就可以让被跳转的 ViewModel 知道信息。

最上面的页面的 ViewModel 是不做功能的,就做跳转,实际上他的跳转逻辑也不需要写,因为底层已经做了跳转的逻辑。

为了模拟读取数据,使用 Task.Delay 假装是在读取数据

         /// <summary>
/// 读取数据
/// </summary>
/// <returns></returns>
public async Task Read()
{
await Task.Delay(1000);
}

页面传参

如果没有使用框架,那么在开发的时候有一个问题,ViewModel 是写在 页面进行创建还是从外面创建然后传进来。

如果写在页面有一个问题是如何把其他页面跳转的信息发送到 ViewModel ,这个框架使用的是在外面创建。

在 UWP 的页面参数是在 OnNavigatedTo 函数拿到。

在刚才的ViewModel 就在读取完信息,就把页面跳转到 WastounowMearhallworcelModel ,这是一个随意的名字

        public override void OnNavigatedTo(object sender, object obj)
{
base.OnNavigatedTo(sender, obj); Navigate(typeof(WastounowMearhallworcelModel));
}

在 WastounowMearhallworcelModel 对应的页面使用 OnNavigatedTo 就可以拿到这个 ViewModel ,需要强转,我之前想使用泛型的方法让页面指定 ViewModel ,但是存在一个文件是 xaml 对泛型支持不好,所以不在 UWP 使用这个方法

        /// <inheritdoc />
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ViewModel = (WastounowMearhallworcelModel) e.Parameter;
DataContext = e.Parameter;
base.OnNavigatedTo(e);
} public WastounowMearhallworcelModel ViewModel { get; set; }

在页面使用泛型请看 win10 uwp 如何让 Page 继承泛型类

现在就可以使用 WastounowMearhallworcelModel ,在 WastounowMearhallworcelModel 里面也可以获得主界面传过来的参数

        /// <inheritdoc />
public override void OnNavigatedTo(object sender, object obj)
{ }

这里的 obj 就是页面导航传过来的参数,也就是原来的 Page 传过来的就是 ViewModel ,在 ViewModel 跳转的就是另一个 ViewModel 传过来的参数。

这样可以去掉 Page 进行调试和测试,因为这时的 ViewModel 完全使用 ViewModel 就可以做到。

但是对于一些交互细节要求比较高的地方,那么就不建议使用 MVVM 来做,如手势移动这些交互。

在进入一个 ViewModel 的时候,需要让他发送消息给其他的 ViewModel ,在继承 ViewModelMessage 就可以使用 Send 函数,发送的消息可以是消息也可以是告诉指定ViewModel如何处理。

发送的消息先会发送到这个 ViewModel 的上一级,如果这个消息指定的 ViewModel 不是上一级的 ViewModel 就会在上一级寻找同级的 ViewModel 。如果找到 消息指定的 ViewModel 再寻找消息对应的处理,把消息交给处理。如果发送的消息是自带处理,就调用消息本身的处理。

所以通过这个方式就可以让 ViewModel 发送消息到另一个 ViewModel ,下面的代码就是 WastounowMearhallworcelModel 发送消息,让主页面跳转到 MeetokaCutusaiModel 的页面

        public void NavigatedMeetokaCutusaiModel()
{
Send(new NavigateMessage(this,typeof(MeetokaCutusaiModel).Name));
}

这样做的设计是解耦,在 WastounowMearhallworcelModel 是完全不知道跳转的逻辑,他只需要知道发送这个消息,就会切换页面。而且页面被切换到 MeetokaCutusaiModel ,轻量框架是可以用来减少 ViewModel 的相关。

这个框架的设计参考了 MVVMCross 和 MVVMLight 只是减少了里面部分功能

参见:

win10 uwp MVVM入门

win10 uwp MVVM 轻量框架

win10 uwp MVVM 语义耦合

2019-11-29-win10-uwp-轻量级-MVVM-框架入门-2.1.5.3199的更多相关文章

  1. Farseer.net轻量级开源框架 入门篇:使用前说明

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 框架性能测试 下一篇:Farseer.net轻量级开源框架 入门篇: 增.删.改. ...

  2. Farseer.net轻量级开源框架 入门篇:逻辑层的选择

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 入门篇:增.删.改.查操作演示 下一篇:Farseer.net轻量级开源框架 入门 ...

  3. Farseer.net轻量级开源框架 入门篇:分类逻辑层

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 缓存逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 ...

  4. Farseer.net轻量级开源框架 入门篇:添加数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 分类逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 ...

  5. Farseer.net轻量级开源框架 入门篇:修改数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 ...

  6. Farseer.net轻量级开源框架 入门篇:删除数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 ...

  7. Farseer.net轻量级开源框架 入门篇:查询数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 下一篇:Farseer.net轻量级开源框架 中级篇: Where条 ...

  8. Farseer.net轻量级开源框架 入门篇:Where条件的终极使用

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 下一篇:Farseer.net轻量级开源框架 中级篇: 事务的使用 ...

  9. 轻量级MVVM框架 Stylet

    这两天试了下Stylet框架,这个框架虽然很小,但是功能齐全,简化了很多MVVM的代码,比如Command,对Dialog,MessageBox都有很好的支持. 开源地址 https://github ...

  10. 2019.11.29 Mysql的数据操作

    为名为name的表增加数据(插入所有字段) insert into name values(1,‘张三’,‘男’,20); 为名为name的表增加数据(插入部分字段) insert into name ...

随机推荐

  1. 最长不重复子串长度,时间复杂度O(n),空间复杂度O(n),Python实现

    def lengthOfLongestSubstring(s): res = 0 d = {} tmp = 0 start = 0 for i in range(len(s)): if s[i] in ...

  2. Uep必填字段校验

    在开发中常常有必填字段, <span style="color:Red">*</span>服务地址:</td><hy:formfield ...

  3. [SQL分页语句的三种方式]

    我们在开发的过程经常会用到数据分页,在网上也可以搜到大量的分页插件.这是在端上控制的;有的是在SQL语句实现分页,这是在数据源上 实现分页的; 今天,我就在总结一下我经常用到的SQL语句分页! 第一种 ...

  4. python安装的各种问题

    在windows上安装python下载mis安装即可. 环境用elipse即可,需要下载pydev插件,配置解释器. 如需用到matplotlib,安装顺序为matplot,numpy,dateuti ...

  5. emqtt 系统主题

    $SYS-系统主题 EMQ 消息服务器周期性发布自身运行状态.MQTT 协议统计.客户端上下线状态到 $SYS/ 开头系统主题. $SYS 主题路径以 “$SYS/brokers/{node}/” 开 ...

  6. Python之异常处理-Exception

    在写python程序时, 不要害怕报错, 也不要怕自己的英语不够好, 不要看到一有红色的字就心里发怂. 其实报的错也是有套路可寻滴~识别了异常的种类, 才能对症下药. 常见异常: Exception ...

  7. 通过JavaScript让页面只刷新一次

    1.充分利用地址栏可带参数的选项,用脚本来取得页面间的传递参数,并不需要后台程序的支持. 2.函数名 function reurl(){ url = location.href; //把当前页面的地址 ...

  8. Python学习之==>面向对象编程(二)

    一.类的特殊成员 我们在Python学习之==>面向对象编程(一)中已经介绍过了构造方法和析构方法,构造方法是在实例化时自动执行的方法,而析构方法是在实例被销毁的时候被执行,Python类成员中 ...

  9. playbook部署mangodb

    playbook文件 [root@localhost ~]# cat deploy_mongo.yaml --- - hosts: webservers become: yes become_meth ...

  10. 关于img标签浏览器自带的边框,清除边框的解决方式(即img[src=""] img无路径情况下,灰色边框去除解决方法)

    详解img[src=""] img无路径情况下,灰色边框去除解决方法 1.Js解决办法 <html> <head> <meta charset=&qu ...