C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码
今天的學(xué)習(xí)內(nèi)容?
今天我們講講Xamarin中的MVVM雙向綁定,嗯..需要有一定的MVVM基礎(chǔ).,具體什么是MVVM - -,請(qǐng)百度,我就不多講了
效果如下:
?
?
正文
1.簡(jiǎn)單的入門(mén)Demo
這個(gè)時(shí)間的功能很簡(jiǎn)單,就是一個(gè)時(shí)間的動(dòng)態(tài)顯示.
我們首先創(chuàng)建一個(gè)基礎(chǔ)的頁(yè)面如下:
<?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>大家可以發(fā)現(xiàn),我們這次多了一些內(nèi)容.
首先,我們會(huì)發(fā)現(xiàn)ContentPage的xmlns定義中多了一個(gè)local的定義.這個(gè)很重要,他是用來(lái)讓我們?cè)趚aml中引用其他程序集中的類(lèi),類(lèi)似于Using的作用.
剩下的BindingContext和Bingding關(guān)鍵字,后面我們慢慢講
接下來(lái),我們創(chuàng)建一個(gè)ViewModel的類(lèi)如下:
public class TimeViewModel : INotifyPropertyChanged
? ? {
? ? ? ? //定義一個(gè)時(shí)間類(lèi)型
? ? ? ? DateTime dateTime;
? ? ? ? //實(shí)現(xiàn)接口的事件屬性
? ? ? ? public event PropertyChangedEventHandler PropertyChanged;
? ? ? ? //創(chuàng)建構(gòu)造函數(shù),定義一個(gè)定時(shí)執(zhí)行程序
? ? ? ? public TimeViewModel()
? ? ? ? {
? ? ? ? ? ? this.DateTime = DateTime.Now;
? ? ? ? ? ? //定義定時(shí)執(zhí)行程序,1秒刷新一下時(shí)間屬性
? ? ? ? ? ? Device.StartTimer(TimeSpan.FromSeconds(1), () =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this.DateTime = DateTime.Now;
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? //定義時(shí)間屬性,創(chuàng)建SetGet方法,在Set中使用PropertyChanged事件,來(lái)更新這個(gè)時(shí)間
? ? ? ? public DateTime DateTime
? ? ? ? {
? ? ? ? ? ? set
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (dateTime != value)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? dateTime = value;
? ? ? ? ? ? ? ? ? ? if (PropertyChanged != null)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? PropertyChanged(this,
? ? ? ? ? ? ? ? ? ? ? ? ? ? new PropertyChangedEventArgs("DateTime"));
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return dateTime;
? ? ? ? ? ? }
? ? ? ? }
? ? }
我們繼承了INotifyPropertyChanged,從類(lèi)名就可以看出來(lái),這個(gè)是關(guān)于實(shí)現(xiàn)屬性變更事件的一個(gè)接口.
他包含一個(gè)PropertyChanged,屬性變更事件,我們需要在每個(gè)屬性變更的時(shí)候(也就是Set中),調(diào)用它
在具體的開(kāi)發(fā)過(guò)程中,如果你需要使用MVVM那么你所有的ViewModel都應(yīng)該繼承它.
很多解釋我都寫(xiě)在了注釋里面,請(qǐng)仔細(xì)看注釋
然后我們回到Xaml中的BindingContext,它的作用就一目了然了,給這個(gè)Xaml控件,綁定一個(gè)上下文對(duì)象,也就是你定義的ViewModel,來(lái)方便你綁定其中的屬性
<Label Text="{Binding DateTime,StringFormat='{0:F}'}">?這句的意思就是,綁定其中的DateTime屬性,并格式化顯示.
我們?cè)跇?gòu)造函數(shù)中啟動(dòng)的定時(shí)程序,就會(huì)一直更新DateTime,對(duì)應(yīng)的,頁(yè)面上也會(huì)一直隨著變更.這樣我們就實(shí)現(xiàn)了一個(gè)基礎(chǔ)的MVVM
效果如圖:
?
?
2.學(xué)會(huì)與控件相聯(lián)系,并綁定命令事件
通過(guò)上面的小栗子,我們學(xué)習(xí)了一下基本的綁定關(guān)系和綁定方法.
那么下面就來(lái)一個(gè)比較復(fù)雜,比較難的例子.效果是這樣的,如圖:
我們創(chuàng)建三個(gè)數(shù)值,他們與控件Slider來(lái)綁定,并控制.更新值的同時(shí),求和.得到NumSun的值.
在界面中,我們有一個(gè)清空的Button來(lái)清除這個(gè)ViewModel中的值.
首先,我們創(chuàng)建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='總數(shù)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>然后創(chuàng)建我們的ViewModel代碼如下:
public class AddNumViewModel : INotifyPropertyChanged
? ? {
? ? ? ? //定義屬性值
? ? ? ? double num1, num2, num3,numSun;
? ? ? ? public event PropertyChangedEventHandler PropertyChanged;
? ? ? ? //定義清空的命令
? ? ? ? public ICommand CleanCommand { protected set; get; }
? ? ? ? public AddNumViewModel()
? ? ? ? {
? ? ? ? ? ? //實(shí)現(xiàn)清空
? ? ? ? ? ? this.CleanCommand = new Command((key) =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this.NumSun = 0;
? ? ? ? ? ? ? ? this.Num1 = 0;
? ? ? ? ? ? ? ? this.Num2 = 0;
? ? ? ? ? ? ? ? this.Num3 = 0;
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 統(tǒng)一的屬性變更事件判斷方法
? ? ? ? /// </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>
? ? ? ? /// 把數(shù)值加起來(lái)的方法(業(yè)務(wù)邏輯)
? ? ? ? /// </summary>
? ? ? ? void SetNewSunNum()
? ? ? ? {
? ? ? ? ? ? this.NumSun = this.Num1 + this.Num2 + this.Num3;
? ? ? ? }
? ? }
很簡(jiǎn)單,我們創(chuàng)建了Num1,Num2,Num3和NumSun四個(gè)屬性.實(shí)現(xiàn)了一個(gè)SetNewSunNum的方法,來(lái)求和.
然后就一一對(duì)應(yīng)的在xaml中綁定了相關(guān)的屬性.所有的Slider綁定中都有個(gè)Mode=TwoWay,意思就是,這個(gè)屬性為雙向綁定,在控件中變更它的同時(shí),也會(huì)在ViewModel中變更.
然后我們?cè)趤?lái)看看清空按鈕的命令綁定.
先解釋一下,為什么會(huì)有命令綁定這個(gè)東西,因?yàn)槲覀兪褂秒p向綁定的時(shí)候,頁(yè)面的點(diǎn)擊事件,并不能直接調(diào)用到ViewModel,所以就衍生了一個(gè)叫命令綁定的東西.來(lái)和我們控件的各種事件相關(guān)聯(lián).
我們回到代碼,會(huì)發(fā)現(xiàn),在AddNumViewModel中,我們定義了一個(gè)繼承自?ICommand的CleanCommand?的命令,并在構(gòu)造函數(shù)中實(shí)現(xiàn)了它
在我們的xaml中,buttom綁定了這個(gè)事件?<Button Text="清空" Command="{Binding CleanCommand}" />
這樣,就可以直接調(diào)用到ViewModel了,當(dāng)然你的命令也可以傳遞參數(shù),如下:
<Button Text="清空" Command="{Binding CleanCommand}" CommandParameter="aaa" />aaa就是你傳遞的參數(shù).
接收也很簡(jiǎn)單,稍微改一下.CleanCommand?如下:
這個(gè)key就是你傳遞進(jìn)來(lái)的參數(shù)了..
?
3.回顧一下.
今天主要學(xué)習(xí)了Xamarin中的MVVM雙向綁定和命令綁定,
需要雙向綁定的類(lèi),需要繼承INotifyPropertyChanged,需要綁定的命令,需要繼承:ICommand
最后,列一下可以使用命令綁定的控件.
Button
MenuItem
ToolbarItem
SearchBar
TextCell(所以也包含ImageCell)
ListView
TapGestureRecognizer
除了SearchBar和?ListView這兩個(gè)控件之外,這些控件都可以使用Command?和CommandParameter?
嗯..,SearchBar定義SearchCommand和SearchCommandParameter屬性,而ListView定義一個(gè)RefreshCommand屬性的類(lèi)型ICommand。
其實(shí)都是一樣的..名字換了一下..
相關(guān)文章:?
C#使用Xamarin開(kāi)發(fā)可移植移動(dòng)應(yīng)用(1.入門(mén)與Xamarin.Forms頁(yè)面),附源碼
.NET Standard@Xamarin.Forms
C#使用Xamarin開(kāi)發(fā)可移植移動(dòng)應(yīng)用(2.Xamarin.Forms布局,本篇很長(zhǎng),注意)附源碼
C#使用Xamarin開(kāi)發(fā)可移植移動(dòng)應(yīng)用(3.Xamarin.Views控件)附源碼
原文地址:http://www.cnblogs.com/GuZhenYin/p/7381973.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Entity Framework Cor
- 下一篇: c# char unsigned_dll