C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码
系列目录
源码地址:https://github.com/l2999019/DemoApp
可以Star一下,随意 - -
说点什么..
嗯..前面3篇就是基础内容..后面就开始逐渐要加深了,进阶篇开始了.
今天的学习内容?
今天我们讲讲Xamarin中的MVVM双向绑定,嗯..需要有一定的MVVM基础.,具体什么是MVVM - -,请百度,我就不多讲了
效果如下:
1.简单的入门Demo
这个时间的功能很简单,就是一个时间的动态显示.
我们首先创建一个基础的页面如下:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:DemoApp.MVVMDemo.ViewModel" x:Class="DemoApp.MVVMDemo.MVVMPageDemo"> <ContentPage.Content> <StackLayout > <Label Text="{Binding DateTime,StringFormat='{0:F}'}"> <Label.BindingContext> <local:TimeViewModel></local:TimeViewModel> </Label.BindingContext> </Label> </StackLayout> </ContentPage.Content> </ContentPage>
大家可以发现,我们这次多了一些内容.
首先,我们会发现ContentPage的xmlns定义中多了一个local的定义.这个很重要,他是用来让我们在xaml中引用其他程序集中的类,类似于Using的作用.
剩下的BindingContext和Bingding关键字,后面我们慢慢讲
接下来,我们创建一个ViewModel的类如下:
public class TimeViewModel : INotifyPropertyChanged { //定义一个时间类型 DateTime dateTime; //实现接口的事件属性 public event PropertyChangedEventHandler PropertyChanged; //创建构造函数,定义一个定时执行程序 public TimeViewModel() { this.DateTime = DateTime.Now; //定义定时执行程序,1秒刷新一下时间属性 Device.StartTimer(TimeSpan.FromSeconds(1), () => { this.DateTime = DateTime.Now; return true; }); } //定义时间属性,创建SetGet方法,在Set中使用PropertyChanged事件,来更新这个时间 public DateTime DateTime { set { if (dateTime != value) { dateTime = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("DateTime")); } } } get { return dateTime; } } }
我们继承了INotifyPropertyChanged,从类名就可以看出来,这个是关于实现属性变更事件的一个接口.
他包含一个PropertyChanged,属性变更事件,我们需要在每个属性变更的时候(也就是Set中),调用它
在具体的开发过程中,如果你需要使用MVVM那么你所有的ViewModel都应该继承它.
很多解释我都写在了注释里面,请仔细看注释
然后我们回到Xaml中的BindingContext,它的作用就一目了然了,给这个Xaml控件,绑定一个上下文对象,也就是你定义的ViewModel,来方便你绑定其中的属性
<Label Text="{Binding DateTime,StringFormat='{0:F}'}"> 这句的意思就是,绑定其中的DateTime属性,并格式化显示.
我们在构造函数中启动的定时程序,就会一直更新DateTime,对应的,页面上也会一直随着变更.这样我们就实现了一个基础的MVVM
效果如图:
2.学会与控件相联系,并绑定命令事件
通过上面的小栗子,我们学习了一下基本的绑定关系和绑定方法.
那么下面就来一个比较复杂,比较难的例子.效果是这样的,如图:
我们创建三个数值,他们与控件Slider来绑定,并控制.更新值的同时,求和.得到NumSun的值.
在界面中,我们有一个清空的Button来清除这个ViewModel中的值.
首先,我们创建xaml代码如下:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:DemoApp.MVVMDemo.ViewModel" x:Class="DemoApp.MVVMDemo.MVVMDemoPage2"> <ContentPage.BindingContext> <local:AddNumViewModel></local:AddNumViewModel> </ContentPage.BindingContext> <ContentPage.Content> <StackLayout> <Label Text="{Binding NumSun,Mode=TwoWay,StringFormat='总数NumSun={0:F2}'}" /> <Label Text="{Binding Num1, StringFormat='Num1 = {0:F2}'}" /> <Slider Value="{Binding Num1,Mode=TwoWay}" /> <Label Text="{Binding Num2, StringFormat='Num2 = {0:F2}'}" /> <Slider Value="{Binding Num2,Mode=TwoWay}" /> <Label Text="{Binding Num3, StringFormat='Num3 = {0:F2}'}" /> <Slider Value="{Binding Num3,Mode=TwoWay}" /> <Button Text="清空" Command="{Binding CleanCommand}" /> </StackLayout> </ContentPage.Content> </ContentPage>
然后创建我们的ViewModel代码如下:
public class AddNumViewModel : INotifyPropertyChanged { //定义属性值 double num1, num2, num3,numSun; public event PropertyChangedEventHandler PropertyChanged; //定义清空的命令 public ICommand CleanCommand { protected set; get; } public AddNumViewModel() { //实现清空 this.CleanCommand = new Command((key) => { this.NumSun = 0; this.Num1 = 0; this.Num2 = 0; this.Num3 = 0; }); } /// <summary> /// 统一的属性变更事件判断方法 /// </summary> /// <param name="propertyName"></param> protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public double Num1 { set { if (num1 != value) { num1 = value; OnPropertyChanged("Num1"); SetNewSunNum(); } } get { return num1; } } public double Num2 { set { if (num2 != value) { num2 = value; OnPropertyChanged("Num2"); SetNewSunNum(); } } get { return num2; } } public double Num3 { set { if (num3 != value) { num3 = value; OnPropertyChanged("Num3"); SetNewSunNum(); } } get { return num3; } } public double NumSun { set { if (numSun != value) { numSun = value; OnPropertyChanged("NumSun"); } } get { return numSun; } } /// <summary> /// 把数值加起来的方法(业务逻辑) /// </summary> void SetNewSunNum() { this.NumSun = this.Num1 + this.Num2 + this.Num3; } }
很简单,我们创建了Num1,Num2,Num3和NumSun四个属性.实现了一个SetNewSunNum的方法,来求和.
然后就一一对应的在xaml中绑定了相关的属性.所有的Slider绑定中都有个Mode=TwoWay,意思就是,这个属性为双向绑定,在控件中变更它的同时,也会在ViewModel中变更.
然后我们在来看看清空按钮的命令绑定.
先解释一下,为什么会有命令绑定这个东西,因为我们使用双向绑定的时候,页面的点击事件,并不能直接调用到ViewModel,所以就衍生了一个叫命令绑定的东西.来和我们控件的各种事件相关联.
我们回到代码,会发现,在AddNumViewModel中,我们定义了一个继承自 ICommand的CleanCommand 的命令,并在构造函数中实现了它
在我们的xaml中,buttom绑定了这个事件 <Button Text="清空" Command="{Binding CleanCommand}" />
这样,就可以直接调用到ViewModel了,当然你的命令也可以传递参数,如下:
<Button Text="清空" Command="{Binding CleanCommand}" CommandParameter="aaa" />
aaa就是你传递的参数.
接收也很简单,稍微改一下.CleanCommand 如下:
这个key就是你传递进来的参数了..
3.回顾一下.
今天主要学习了Xamarin中的MVVM双向绑定和命令绑定,
需要双向绑定的类,需要继承INotifyPropertyChanged,需要绑定的命令,需要继承:ICommand
最后,列一下可以使用命令绑定的控件.
-
Button
-
MenuItem
-
ToolbarItem
-
SearchBar
-
TextCell(所以也包含
ImageCell
) -
ListView
-
TapGestureRecognizer
除了SearchBar和
ListView这两个控件
之外,这些控件都可以使用Command
和CommandParameter
嗯..,SearchBar
定义SearchCommand
和SearchCommandParameter
属性,而ListView
定义一个RefreshCommand
属性的类型ICommand
。
其实都是一样的..名字换了一下..
嗯..没啥好说的..持续更新中..
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
C#使用Xamarin开发可移植移动应用(3.Xamarin.Views控件)附源码
原文: C#使用Xamarin开发可移植移动应用(3.Xamarin.Views控件)附源码 前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. .NET core2.0 发布了,刺激,大致看了一下,很不错,打算后期学习.(不出意外,应该也会写个小系列). 虽然官方推荐用共享类库创建新的类库..然而我这个Demo还是使用的可移植.. 嗯..解释一下 为什么暂时没用共享类库.. 有些小BUG 可能是为了迎合其他类型的项目..所以在共享类库里创建的Page并不能很好的结合 - - 类似如下: 正常的应该是这样 呃其实我前面也说过这个,这个解决方案也很简单..在PCL项目里创建了..在复制过去..就好了..就是正常的..类似下面: 今天的学习内容? 嗯..今天主要学习Xamarin中的各种原装控件 比较多..你们可以不看..或者随便看看..我会把这些控件的相关属性都翻译一下,列出来,就当这是一个控件的查询字典吧.. 效果如下: 正文 1.Acti...
- 下一篇
C#使用Xamarin开发可移植移动应用(5.进阶篇显示弹出窗口与通讯中心)附源码
原文: C#使用Xamarin开发可移植移动应用(5.进阶篇显示弹出窗口与通讯中心)附源码 前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 没啥好说的.开干吧. 今天的学习内容? 今天的内容比较简单. 就几个弹出框和内置的消息通讯中心. 如图: 正文 1.xamarin中的弹出窗 xamarin帮我们把各个系统的弹出窗做了2个统一的类. 1.DisplayAlert 2.DisplayActionSheet 我们就来一一看看 DisplayAlert,其实很简单,就是一个类似于HTML的alert的弹出层.当然,你也可以作为commit来使用,代码如下: alert的使用方式: private void Button_Clicked(object sender, EventArgs e) { DisplayAlert("提示", "这里是提示信息", "确定"); } commit的使用方式: private async void But...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- 设置Eclipse缩进为4个空格,增强代码规范
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6