博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码
阅读量:5141 次
发布时间:2019-06-13

本文共 5965 字,大约阅读时间需要 19 分钟。

原文:

前言

系列目录

源码地址:

可以Star一下,随意 - -

说点什么..

嗯..前面3篇就是基础内容..后面就开始逐渐要加深了,进阶篇开始了.

 

今天的学习内容?

今天我们讲讲Xamarin中的MVVM双向绑定,嗯..需要有一定的MVVM基础.,具体什么是MVVM - -,请百度,我就不多讲了

效果如下:

 

 

正文

1.简单的入门Demo

这个时间的功能很简单,就是一个时间的动态显示.

我们首先创建一个基础的页面如下:

大家可以发现,我们这次多了一些内容.

首先,我们会发现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代码如下:

 

然后创建我们的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;            });        }        ///         /// 统一的属性变更事件判断方法        ///         ///         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;            }        }        ///         /// 把数值加起来的方法(业务逻辑)        ///         void SetNewSunNum()        {            this.NumSun = this.Num1 + this.Num2 + this.Num3;        }    }

很简单,我们创建了Num1,Num2,Num3和NumSun四个属性.实现了一个SetNewSunNum的方法,来求和.

然后就一一对应的在xaml中绑定了相关的属性.所有的Slider绑定中都有个Mode=TwoWay,意思就是,这个属性为双向绑定,在控件中变更它的同时,也会在ViewModel中变更.

然后我们在来看看清空按钮的命令绑定.

先解释一下,为什么会有命令绑定这个东西,因为我们使用双向绑定的时候,页面的点击事件,并不能直接调用到ViewModel,所以就衍生了一个叫命令绑定的东西.来和我们控件的各种事件相关联.

我们回到代码,会发现,在AddNumViewModel中,我们定义了一个继承自 ICommandCleanCommand 的命令,并在构造函数中实现了它

在我们的xaml中,buttom绑定了这个事件 <Button Text="清空" Command="{Binding CleanCommand}" />

这样,就可以直接调用到ViewModel了,当然你的命令也可以传递参数,如下:

aaa就是你传递的参数.

接收也很简单,稍微改一下.CleanCommand 如下:

这个key就是你传递进来的参数了..

 

 

3.回顾一下.

今天主要学习了Xamarin中的MVVM双向绑定和命令绑定,

需要双向绑定的类,需要继承INotifyPropertyChanged,需要绑定的命令,需要继承:ICommand

最后,列一下可以使用命令绑定的控件.

  • Button

  • MenuItem

  • ToolbarItem

  • SearchBar

  • TextCell(所以也包含ImageCell

  • ListView

  • TapGestureRecognizer

除了SearchBar和 ListView这两个控件之外,这些控件都可以使用Command 和CommandParameter 

嗯..,SearchBar定义SearchCommandSearchCommandParameter属性,而ListView定义一个RefreshCommand属性的类型ICommand

其实都是一样的..名字换了一下..

 

 

 

 

 

 

 

写在最后

嗯..没啥好说的..持续更新中..

posted on
2018-09-10 11:38 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/9618230.html

你可能感兴趣的文章
Oracle注意事项
查看>>
容器(docker)内运行Nginx
查看>>
WinCE应用程序开发---打开或另存为对话框
查看>>
央视影音 for Mac 1.2.1 中文版 – CCTV和地方卫视直播软件
查看>>
谈谈市面上无线路由器的性能和芯片
查看>>
PHP 开发工具【2】
查看>>
『数据仓库』学习记录(1)
查看>>
CI Weekly #15 | 据说新版 flow.ci Dashboard 界面很酷
查看>>
短信编码总结
查看>>
了解HTML和Css样式
查看>>
关于settimer的一些新认识
查看>>
[转]ExtJs4 笔记(13) Ext.menu.Menu 菜单、Ext.draw.Component 绘图、Ext.resizer.Resizer 大小变更...
查看>>
1-5-06:奥运奖牌计数
查看>>
Windows下Python连接sqlite3数据库
查看>>
Javascript 类与静态类的实现(续)
查看>>
shim和polyfill有什么区别
查看>>
Failed to load the JNI shared library “E:/2000/Java/JDK6/bin/..jre/bin/client/jvm.dll
查看>>
Zabbix3.4服务器的搭建--CentOS7
查看>>
〖Python〗-- IO多路复用
查看>>
栈(括号匹配)
查看>>