C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码
今天的學習內容?
今天我們講講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。
其實都是一樣的..名字換了一下..
相關文章:?
C#使用Xamarin開發可移植移動應用(1.入門與Xamarin.Forms頁面),附源碼
.NET Standard@Xamarin.Forms
C#使用Xamarin開發可移植移動應用(2.Xamarin.Forms布局,本篇很長,注意)附源碼
C#使用Xamarin開發可移植移動應用(3.Xamarin.Views控件)附源碼
原文地址:http://www.cnblogs.com/GuZhenYin/p/7381973.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
總結
以上是生活随笔為你收集整理的C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Entity Framework Cor
- 下一篇: .NET Core 2.0 特性介绍和使