XAML in Xamarin.Forms 基礎篇 電子書

特別說明

2018/06/12

Xamarin.Forms 圖片資料綁定的處理

相信大家對於如何在 Xamarin.Forms 中進行字串型別的資料綁定都非常的孰悉,今天,我們來練習如何進行圖片的資料綁定操作。我們的模擬情境為:當我們使用 HttpClient 進行非同步網頁讀取之後,便會變更要綁定的圖片內容,顯示出不同的圖片內容,這些圖片內容將會存在於原生專案。
首先,我們先建立的 Xamarin.Forms for Prism 的專案,並且完成 PropertyChanged.Fody 的套件安裝與設定工作,接著,要把這兩個圖片檔案
Facebook Facebook
拖拉到各原生專案的圖片資源所在資料夾內,下圖示 Android 原生專案內的 Resource/drawable 資料夾,裡面就有這兩個圖片檔案。
Image Data Binding
在這個範例中,僅有一個頁面,從底下的 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 專案內的執行結果畫面截圖
Image Data Binding Image Data Binding
Image Data Binding Image Data Binding



沒有留言:

張貼留言