相信大家對於如何在 Xamarin.Forms 中進行字串型別的資料綁定都非常的孰悉,今天,我們來練習如何進行圖片的資料綁定操作。我們的模擬情境為:當我們使用 HttpClient 進行非同步網頁讀取之後,便會變更要綁定的圖片內容,顯示出不同的圖片內容,這些圖片內容將會存在於原生專案。
了解更多關於 [Xamarin.Android] 的使用方式
了解更多關於 [Xamarin.iOS] 的使用方式
了解更多關於 [Xamarin.Forms] 的使用方式
了解更多關於 [Hello, Android:快速入門] 的使用方式
了解更多關於 [Hello, iOS – 快速入門] 的使用方式
了解更多關於 [Xamarin.Forms 快速入門] 的使用方式
首先,我們先建立的 Xamarin.Forms for Prism 的專案,並且完成 PropertyChanged.Fody 的套件安裝與設定工作,接著,要把這兩個圖片檔案
拖拉到各原生專案的圖片資源所在資料夾內,下圖示 Android 原生專案內的 Resource/drawable 資料夾,裡面就有這兩個圖片檔案。
在這個範例中,僅有一個頁面,從底下的 XAML 內容中,我們可以很清楚的看到,圖片控制項 Image 的 Source 屬性,是綁定到 ViewModel 中的 ShowImage C# Property 上。另外,還有一個按鈕,當按下這個按鈕之後,就會透過 HttpClient 使用非同步的方式抓取 www.google.com 網頁內容,緊接著就會變更 ShowImage 這個字串屬性內容,當然,我們就可以從螢幕上,看到圖片有所變動了。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XFImgBinding.Views.MainPage"
Title="{Binding Title}">
<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="Welcome to Xamarin Forms and Prism!" />
<Image Source="{Binding ShowImage}"
WidthRequest="200" HeightRequest="200"/>
<Button Text="呼叫 Web API"
Command="{Binding CallWebCommand}"/>
</StackLayout>
</ContentPage>
底下為這個頁面的 ViewModel 程式碼,在這裡,我們撰寫了兩個方法,GetWebAndShowImage & GetWebAndShowImageAsync,兩者皆為非同步的方法,不過,後者是可以透過 await 關鍵字來等候 GetWebAndShowImageAsync 這個方法執行完畢後,繼續來執行的方法;而前者,因為使用了 async void GetWebAndShowImage 這樣的函式標示,因此,呼叫這個函式雖然是個非同步的運算,但是,卻是屬於設後不理的運作模式,也就是說,我們無法掌握 GetWebAndShowImage 這個非同步方法何時會執行完畢。
另外,在建構函式內,我們最後呼叫了 GetWebAndShowImage() 這個方法,這樣的做法非常的不恰當,因為,建構函式內的敘述,不應該執行這些非同步的方法,而且這些建構式內的敘述都應該要可以在很短的時間內執行完成,這樣,才不會影響這個 ViewModel 物件建立與取得的時間。若在 Xamarin.Forms 專案內,真的有甚麼工作需要在建構函式內,需要呼叫這些非同步的方法,建議寫在 OnNavigatedTo 事件內。
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;
using Prism.Events;
using Prism.Navigation;
using Prism.Services;
namespace XFImgBinding.ViewModels
{
public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
{
public event PropertyChangedEventHandler PropertyChanged;
public int ImageStatus { get; set; }
public string ShowImage { get; set; }
public DelegateCommand CallWebCommand { get; set; }
private readonly INavigationService _navigationService;
public MainPageViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
CallWebCommand = new DelegateCommand(async () =>
{
await GetWebAndShowImageAsync();
});
GetWebAndShowImage();
}
public async void GetWebAndShowImage()
{
var client = new HttpClient();
var fooTmp = await client.GetStringAsync("https://www.google.com");
ShowImage = $"facebook{(ImageStatus++ % 2) + 1}.png";
}
public async Task GetWebAndShowImageAsync()
{
var client = new HttpClient();
var fooTmp = await client.GetStringAsync("https://www.google.com");
ShowImage = $"facebook{(ImageStatus++ % 2) + 1}.png";
}
public void OnNavigatedFrom(NavigationParameters parameters)
{
}
public void OnNavigatingTo(NavigationParameters parameters)
{
}
public void OnNavigatedTo(NavigationParameters parameters)
{
}
}
}
這裡是在 Android & UWP 專案內的執行結果畫面截圖