Xamarin.Android和UWP之MVVM的简单使用(二)

0x01 前言

前面一篇,Xamarin.Android和UWP之MVVM的简单使用(一),主要讲了MvvmLight的简单使用

这篇主要讲讲MvvmCross的简单使用,例子的话,还是和上篇的一样。直接进正题吧,不废话了。

 

0x02 简单的MVVM(mvvmcross) Demo

新建一个类库项目:Catcher.MVVMDemo.Day01CrossCore

添加一个ViewModels文件夹,同时添加一个MainViewModel

 1 using MvvmCross.Core.ViewModels;
 2 namespace Catcher.MVVMDemo.Day01CrossCore.ViewModels
 3 {
 4     public class MainViewModel : MvxViewModel
 5     {
 6         public MainViewModel() { }
 7         private string _input;
 8         public string Input
 9         {
10             get
11             {
12                 return _input;
13             }
14             set
15             {
16                 _input = value;
17                 RaisePropertyChanged(() => Input);
18             }
19         }
20     }
21 }

 

这里的ViewModel继承的是MvxViewModel。

在项目根路径添加一个App.cs

 1 using Catcher.MVVMDemo.Day01CrossCore.ViewModels;
 2 using MvvmCross.Core.ViewModels;
 3 namespace Catcher.MVVMDemo.Day01CrossCore
 4 {
 5     public class App : MvxApplication
 6     {
 7         public override void Initialize()
 8         {
 9             RegisterAppStart<MainViewModel>();
10         }        
11     }
12 }

注册MainViewModel为启动的第一个视图模型

到这里,Xamarin.Android和UWP的公共部分已经完成了。

第一个例子(Xamarin.Android):

新建一个Android项目:Catcher.MVVMDemo.Day01DroidByMvvmCross

在根目录添加一个Setup.cs

 1 using Android.Content;
 2 using MvvmCross.Core.ViewModels;
 3 using MvvmCross.Droid.Platform;
 4 using Catcher.MVVMDemo.Day01CrossCore;
 5 namespace Catcher.MVVMDemo.Day01DroidByMvvmCross
 6 {
 7     public class Setup : MvxAndroidSetup
 8     {
 9         public Setup(Context applicationContext)
10             : base(applicationContext)
11         {
12         }
13         protected override IMvxApplication CreateApp()
14         {
15             return new App();
16         } 
17     }
18 }

在Setup中,主要是返回了我们在Core里面编写的App.cs

然后修改我们的Main.axml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:local="http://schemas.android.com/apk/res-auto"
 4     android:orientation="vertical"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent">
 7     <EditText
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         local:MvxBind="Text Input" />
11     <TextView
12         android:layout_width="match_parent"
13         android:layout_height="wrap_content"
14         local:MvxBind="Text Input" />
15 </LinearLayout>

通过local:MvxBind来实现绑定。

新建一个文件夹Activities,同时添加一个MainActivity

 1 using Android.App;
 2 using MvvmCross.Droid.Views;
 3 namespace Catcher.MVVMDemo.Day01DroidByMvvmCross.Activities
 4 {
 5     [Activity(Label = "MvvmCross", MainLauncher = true)]
 6     public class MainActivity : MvxActivity
 7     {
 8         protected override void OnViewModelSet()
 9         {
10             SetContentView(Resource.Layout.Main);
11         }
12     }
13 }

 

Activity的代码很简单,就是指定视图。

到这里已经可以成功运行了,效果如下:

第二个例子(UWP):

步骤基本与Xamarin.Android一致!

新建一个UWP项目:Catcher.MVVMDemo.Day01UWPByMvvmCross

添加一个Setup.cs

 1 using MvvmCross.Core.ViewModels;
 2 using MvvmCross.WindowsUWP.Platform;
 3 using Windows.UI.Xaml.Controls;
 4 namespace Catcher.MVVMDemo.Day01UWPByMvvmCross
 5 {
 6     public class Setup : MvxWindowsSetup
 7     {
 8         public Setup(Frame rootFrame) : base(rootFrame)
 9         {
10         }
11         protected override IMvxApplication CreateApp()
12         {
13             return new Day01CrossCore.App();
14         }
15     }
16 }

注意与Android的区别!!

修改App.xaml.cs,将设置启动页注释掉,换成我们刚才的Setup.cs,具体如下:

 1           if (e.PrelaunchActivated == false)
 2             {
 3                 if (rootFrame.Content == null)
 4                 {
 5                    
 6                     //rootFrame.Navigate(typeof(MainPage), e.Arguments);
 7                     var setup = new Setup(rootFrame);
 8                     setup.Initialize();
 9                     var start = Mvx.Resolve<IMvxAppStart>();
10                     start.Start();
11                 }              
12                 Window.Current.Activate();
13             }

 

把新建项目生成的MainPage干掉,同时在根目录添加一个Views文件夹,用来存放我们的Page

新建一个MainPage.xaml,修改布局如下:

 1 <views:MvxWindowsPage
 2     x:Class="Catcher.MVVMDemo.Day01UWPByMvvmCross.Views.MainPage"
 3     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 5     xmlns:local="using:Catcher.MVVMDemo.Day01UWPByMvvmCross.Views"
 6     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 7     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 8         xmlns:views="using:MvvmCross.WindowsUWP.Views"
 9     mc:Ignorable="d">
10     <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
11         <StackPanel Margin="20">
12             <TextBlock FontSize="14" HorizontalAlignment="Center" Text="MvvmCross UWP Demo" />
13             <TextBox  
14                 x:Name="txtInput"
15                 />
16             <TextBlock Text="{Binding ElementName=txtInput,Path=Text}" />
17         </StackPanel>
18     </Grid>
19 </views:MvxWindowsPage>

要注意的是,用的是MvvmCross的布局MvxWindosPage

并且,MainPage.xaml.cs也要修改!!

 1 using MvvmCross.WindowsUWP.Views;
 2 namespace Catcher.MVVMDemo.Day01UWPByMvvmCross.Views
 3 {    
 4     public sealed partial class MainPage : MvxWindowsPage
 5     {
 6         public MainPage()
 7         {
 8             this.InitializeComponent();
 9         }
10     }
11 }

都是用MvvmCross自己的东西!如果忘记修改,运行效果是一片黑。

到这里已经OK了,效果如下 

 

0x03 MVVM(mvvmcross) 登陆Demo

登陆失败时要有个对话框提示,我们要先新建一个IDialogService

1 namespace Catcher.MVVMDemo.Day01CrossCore
2 {
3     public interface IDialogService
4     {
5         void Alert(string message, string title, string okbtnText);
6     }
7 }

在刚才的类库项目中添加一个LoginViewModel

 1 using MvvmCross.Core.ViewModels;
 2 namespace Catcher.MVVMDemo.Day01CrossCore.ViewModels
 3 {
 4     public class LoginViewModel : MvxViewModel
 5     {
 6         private readonly IDialogService _dialogService;
 7         public LoginViewModel(IDialogService dialogService)
 8         {
 9             _dialogService = dialogService;
10         }
11         private string _Name;
12         public string Name
13         {
14             get
15             {
16                 return _Name;
17             }
18             set
19             {
20                 _Name = value;
21                 RaisePropertyChanged(()=>Name);
22             }
23         }
24         private string _password;
25         public string Password
26         {
27             get
28             {
29                 return _password;
30             }
31             set
32             {
33                 _password = value;
34                 RaisePropertyChanged(()=>Password);
35             }
36         }
37         private IMvxCommand _loginCommand;
38         public virtual IMvxCommand LoginCommand
39         {
40             get
41             {
42                 _loginCommand = _loginCommand ?? new MvxCommand(Login);
43                 return _loginCommand;
44             }
45         }
46         private void Login()
47         {
48             if (Name=="catcher"&&Password=="123")
49             {
50                 ShowViewModel<MainViewModel>();
51             }
52             else
53             {
54                 _dialogService.Alert("check your name and password", "Infomation", "OK");
55             }
56         }
57     }
58 }

登陆的逻辑处理还是和上一篇一样。

修改我们的App.cs

 1 using Catcher.MVVMDemo.Day01CrossCore.ViewModels;
 2 using MvvmCross.Core.ViewModels;
 3 using MvvmCross.Platform;
 4 using MvvmCross.Platform.IoC;
 5 namespace Catcher.MVVMDemo.Day01CrossCore
 6 {
 7     public class App : MvxApplication
 8     {
 9         public override void Initialize()
10         {
11             CreatableTypes()
12             .EndingWith("Service")
13             .AsInterfaces()
14             .RegisterAsLazySingleton();
15 
16             RegisterAppStart<LoginViewModel>();
17             //demo 1
18             //RegisterAppStart<MainViewModel>();
19         }        
20     }
21 }

第三个例子(Xamarin.Android):

在Catcher.MVVMDemo.Day01DroidByMvvmCross中添加一个Services文件夹

同时添加一个DialogService去实现我们刚才定义的IDialogService接口。

 1 using Android.App;
 2 using MvvmCross.Platform;
 3 using Catcher.MVVMDemo.Day01CrossCore;
 4 using MvvmCross.Platform.Droid.Platform;
 5 namespace Catcher.MVVMDemo.Day01DroidByMvvmCross.Services
 6 {
 7     public class DialogService : IDialogService
 8     {
 9         /// <summary>
10         /// show the alert dialog
11         /// </summary>
12         /// <param name="message">the message of the dialog</param>
13         /// <param name="title">the title of the dialog</param>
14         /// <param name="okbtnText">the text of the button</param>
15         public void Alert(string message, string title, string okbtnText)
16         {
17             //activity
18             var topActivity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
19             var context = topActivity.Activity;
20             //alert dialog
21             var adb = new AlertDialog.Builder(context);
22             adb.SetTitle(title);
23             adb.SetMessage(message);            
24             adb.SetPositiveButton(okbtnText, (sender, args) => { });
25             adb.Create().Show();
26         }        
27     }
28 }

这里用到了AlertDialog。

在Setup.cs中注册一下这个Service,重写InitializeFirstChance 方法

1       protected override void InitializeFirstChance()
2         {
3             base.InitializeFirstChance();
4             Mvx.RegisterSingleton<IDialogService>(() => new DialogService());
5         }

添加一个login.axml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:local="http://schemas.android.com/apk/res-auto"
 4     android:orientation="vertical"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent">
 7     <EditText
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         android:hint="enter your name"
11         local:MvxBind="Text Name" />
12     <EditText
13         android:layout_width="match_parent"
14         android:layout_height="wrap_content"
15         android:inputType="textPassword"
16         android:hint="enter your password"
17         local:MvxBind="Text Password" />
18     <Button
19         android:layout_width="match_parent"
20         android:layout_height="wrap_content"
21         android:text="Login"
22         local:MvxBind="Click LoginCommand" />
23 </LinearLayout>

在Activities文件夹添加一个LoginActivity

 1 using Android.App;
 2 using MvvmCross.Droid.Views;
 3 namespace Catcher.MVVMDemo.Day01DroidByMvvmCross.Activities
 4 {
 5     [Activity(Label = "MvvmCross", MainLauncher = true)]
 6     public class LoginActivity : MvxActivity
 7     {
 8         protected override void OnViewModelSet()
 9         {
10             SetContentView(Resource.Layout.login);
11         }
12     }
13 }

去掉,MainActivity中的Mainlauncher=true

OK,效果如下:

第四个例子(UWP):

在Catcher.MVVMDemo.Day01UWPByMvvmCross中添加一个Services文件夹

同时添加一个DialogService去实现我们刚才定义的IDialogService接口。

 1 using Catcher.MVVMDemo.Day01CrossCore;
 2 using System;
 3 using Windows.UI.Xaml.Controls;
 4 namespace Catcher.MVVMDemo.Day01UWPByMvvmCross.Services
 5 {
 6     public class DialogService : IDialogService
 7     {
 8         public async void Alert(string message, string title, string okbtnText)
 9         {            
10             var dialog = new ContentDialog()
11             {
12                 Content = message,
13                 Title= title,
14                 PrimaryButtonText = okbtnText
15             };
16             dialog.PrimaryButtonClick += (s, e) => { };
17             await dialog.ShowAsync();           
18         }
19     }
20 }

这里用ContentDialog去实现这个提示。

在Setup.cs中注册一下这个Service,重写InitializeFirstChance 方法

1       protected override void InitializeFirstChance()
2         {
3             base.InitializeFirstChance();
4             Mvx.RegisterSingleton<IDialogService>(() => new DialogService());
5         }

在Views文件夹添加一个LoginPage.xaml

 1 <views:MvxWindowsPage
 2     x:Class="Catcher.MVVMDemo.Day01UWPByMvvmCross.Views.LoginPage"
 3     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 5     xmlns:local="using:Catcher.MVVMDemo.Day01UWPByMvvmCross.Views"
 6     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 7     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 8     xmlns:views="using:MvvmCross.WindowsUWP.Views"    
 9     mc:Ignorable="d">
10     <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
11         <Grid.RowDefinitions>
12             <RowDefinition Height="*"></RowDefinition>
13             <RowDefinition Height="*"></RowDefinition>
14             <RowDefinition Height="*"></RowDefinition>
15             <RowDefinition Height="*"></RowDefinition>
16             <RowDefinition Height="5*"></RowDefinition>
17         </Grid.RowDefinitions>
18         <TextBox Grid.Row="1" Margin="15" Height="20" Text="{Binding Name,Mode=TwoWay}" PlaceholderText="enter you name" />
19         <PasswordBox Grid.Row="2" Margin="15" Height="20" Password="{Binding Password,Mode=TwoWay}" PasswordChar="*" PlaceholderText="enter your password" />
20         <Button Grid.Row="3" Margin="15,10" Content="Login" Command="{Binding LoginCommand}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"   />
21     </Grid>
22 </views:MvxWindowsPage>

 

LoginPage.xaml.cs

 1 using Catcher.MVVMDemo.Day01CrossCore.ViewModels;
 2 using MvvmCross.WindowsUWP.Views;
 3 namespace Catcher.MVVMDemo.Day01UWPByMvvmCross.Views
 4 {    
 5     public sealed partial class LoginPage :MvxWindowsPage
 6     {
 7         public new LoginViewModel ViewModel
 8         {
 9             get { return (LoginViewModel)base.ViewModel; }
10             set { base.ViewModel = value; }
11         }
12         public LoginPage()
13         {
14             this.InitializeComponent();
15         }
16     }
17 }

 

OK,效果如下 :

 

0x04 简单总结

MvvmCross用起来跟MvvmLight基本是一样

ViewModel这一块与MvvmLight的ViewModel基本没有太大的差别

其他方面,复杂一点的时候,工作量基本差不多,各有各的好,使用的话,都是看个人的兴趣爱好。

 

MvvmCross也在不断更新,昨天是4.1.5版本,今天就4.1.6了。

官网:https://mvvmcross.com/

Github:https://github.com/MvvmCross

 

转载于:https://www.cnblogs.com/catcher1994/p/5526961.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/294123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ExtJs 带分页的comboBox

ExtJs 带分页的comboBox 如何得到当前第几页&#xff1f; 希望技术牛人能帮帮我&#xff0c;也可以加我扣扣【445958】&#xff0c; 交流JAVA Ext 框架等方面的技术&#xff01;转载于:https://blog.51cto.com/ajiao13/1133773

软件工程之个人项目--词频统计

不得不说对于菜鸟级的我&#xff0c;这是一次心酸的经历啊。。。自打接到王老师布置的这个任务&#xff08;个人项目&#xff09;之后&#xff0c;我心里一直在想着自己要用哪种语言来完成我的任务。以前多多少少写过一些程序的&#xff0c;这又想起了数据库小学期与永哥和小强…

史上最被低估的神级学科,看完忍不住感慨“它”也太重要了!

▲ 点击查看著名物理学家、数学家曾说&#xff1a;几何学的简洁美&#xff0c;却又是几何学之所以完美的核心存在。几何始于数学&#xff0c;但它的意义和影响却远超数学。一个个枯燥的数字和一个个简单的图形&#xff0c;却可以帮助我们解决很多问题&#xff0c;了解自然的规律…

.NET6之MiniAPI(三):Response

MiniAPI中&#xff0c;Response的返回数据有三种格式&#xff0c;IResult&#xff0c;string&#xff0c;json&#xff1a;ValueTask<string> - 这包括 string 和 Task<string>T&#xff08;任何其他类型&#xff0c;返回前端时转成json&#xff09;- 这包括 Task&…

ffmpeg speex转换为mp3或者aac

2019独角兽企业重金招聘Python工程师标准>>> 输入&#xff1a; flv格式&#xff0c;视频264编码&#xff0c;音频speex编码 -8:[rootandrew ffmpeg-3.0./ffprobe test_speex1.flv 32:ffprobe version 3.0-static32: Copyright (c) 2007-2016 the FFmpeg developers3…

c语言给bmp图片加滤镜,关于BMP位图透明通道的详解制作教程, 教你输出透明的BMP位图...

我是sjmhiex啊月谢谢大家的支持 百度贴吧&#xff1a;sjmhiex吧QQ群&#xff1a;243153684BMP支持透明比较常见的方法有两种&#xff1a; 一种是32位图&#xff0c;直接就可以是透明的&#xff0c;还可以是半透明效果&#xff0c;一般都是用PNG转成的&#xff0c;或者在保存图…

Android之Lollipop DevicePolicyManager学习(上)

Android 5.0(lollipop)发布之后&#xff0c;看特性文档增加了不少有趣的东西。 最近花了一些时间&#xff0c;研究了下其中Managed Profile的概念&#xff0c;简称MP&#xff0c;记录下来作为一些经验&#xff0c;有需要的同学请参考。 简介 Managed Profile&#xff0c;简称被…

简述JQuery,Extjs,YUI,Prototype,Dojo等JS框架的区别和应用场景

随着web2.0的彪悍发展&#xff0c;以及浏览器端所承载的工作越来越大&#xff08;在不是很影响性能的情况下&#xff0c;开发者都习惯把能用浏览器做的事儿都让浏览器做&#xff0c;以减轻服务器的压力和带宽费用等&#xff09;。所以Javascript已经成为了web开发最最基本的要求…

怎么向小学生解释欧拉公式 e^(πi)+1=0?

全世界只有3.14 % 的人关注了爆炸吧知识前几天&#xff0c;超模君空投了一个包裹给8岁表妹。不到三秒&#xff0c;表妹就从包裹里面拿出来一条毛毯&#xff1a;表哥&#xff0c;这个毛绒绒的毯子好舒服&#xff0c;我披着毯子写作业很暖和&#xff0c;但这个图案是啥&#xff0…

正式发布!Azure Functions OpenAPI Extension

微软中国MSDN 点击上方蓝字关注我们距离Azure Functions OpenAPI Extension的预览版发布已有一年的时间&#xff0c;今天&#xff0c;我们很开心地宣布它已经正式发布了&#xff01;该版本支持.NET Core 2.1 (LTS)、3.1 (LTS)、.NET 5 和 .NET 6 (LTS)的同时&#xff0c;它还支…

Java中数据是如何存储

2019独角兽企业重金招聘Python工程师标准>>> 一&#xff1a;JAVA中数据的存储方式 ①&#xff1a;寄存器&#xff1a;这是最快的存储区&#xff0c;因为它位于不同于其他存储区的地方———处理器内部。但是寄存器的数量极其有限&#xff0c;所以寄存器根据需求进行…

Android之Lollipop DevicePolicyManager学习(下)

转载&#xff1a;http://blog.csdn.net/guiyu_1985/article/details/42968781 3. 如何在主账户与被管理者账户之间做数据通信。 a) 什么是userID 刚才提到&#xff0c;Lollipop用来区分主账户与被管理账户的其实是一个int型数值userID。 从UserHandler.class可…

详解:从Greenplum、Hadoop到现在的阿里大数据技术

对于企业来说&#xff0c;但是到底云计算是什么呢&#xff1f;相信很多企业都有这样的困惑&#xff0c;让我们一起回到这个原始的起点探讨究竟什么是云计算&#xff1f;云计算对于企业而言到底意味什么&#xff1f;云计算的三条发展路径及三种落地形态 当回到最初的起点再审视云…

技术分享 | 【构建服务端SDK】之连接中心统一调用SDK

源宝导读&#xff1a;微服务架构与传统的单体式方案的最大不同是微服务将应用的核心功能拆分成多项服务。每项服务可以单独构建和部署。服务之间需要互相通信。假设服务间每次通信都需要在调用方编码操作&#xff0c;那么必定会增加很大的工作量&#xff0c;并且造成代码冗余并…

Tcp连接的七次握手浅析

连接的三次握手 客户端向服务器发送SYN请求 服务器发送ACK回应请求&#xff0c;并同时发送一个SYN的请求给客户端 客户端回应ACK应答 关闭的四次握手 对于关闭流程&#xff0c;一共有三种情况&#xff1a;客户端主动关闭&#xff0c;服务器端主动关闭&#xff0c;客户端和服务器…

VS2022安装教程和使用说明来了

我看很多小伙伴已经开始迫不及待的安装VS2022了&#xff0c;虽然我也安装了VS2022&#xff0c;但是我依旧使用VS2019。因为我觉得适合我的才是最好的&#xff0c;并非是最新的&#xff0c;所以大家在使用的时候&#xff0c;根据实际需求选择开发工具&#xff0c;不要一味追求最…