XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2018/06/16

Xamarin.Forms 的 Switch 控制項的資料異動偵測與設計方法

在這篇文章中,我們將會來探討這樣的頁面使用情境該如何進行設計,請參考下圖,在這個頁面中,將會有三個 Switch 控制項,我們希望能夠做到這三個控制項彼此之間的設定選擇是互斥的,也就是,類似一個 Radio Button 的變形應用;當我們選擇了 選項2 之後,選項1就會變成沒有被選擇狀態,同樣的,當選擇了 選項3,此時,選項1,選項2 就會變成沒有被選擇的狀態。
Xamarin.Forms Switch Controller
由於 Switch 這個控制項並沒有相對應可以使用命令 Command(其實,這個控制像是沒有提供任何的 命令),這個時候,我們第一個想到的處理方式,就是使用 Prism 提供的 Behavior 行為機制 , 您可參考 Using the EventToCommandBehavior ,設定當 Switch 的 Toggled 事件被觸發的時候,便可以執行 ViewModel 中指定的 DelegateCommand 的委派方法。
不過,在這篇文章中,我們將要來說明另外一種做法,那就是使用我們安裝好的 PropertyChanged.Fody 這個 NuGet 套件所提供的功能,那就是我們可以針對所綁定的資料,設計一個事件方法,一旦這個綁定的資料有所異動的時候,相對應的事件方法就會被執行。

建立測試專案

  • 首先,我們先使用 Prism Template Pack 擴充功能所提供的專案樣板,建立起一個 Xamarin.Forms 專案,在這裡我們僅選擇 Android / iOS / UWP 類型的專案;接著,我們需要把 PropertyChanged.Fody NuGet 套件安裝到 .NET Standard 專案類別庫內,並且安裝 FodyWeavers.xml 檔案。
  • 我們來設計這篇文章中使用的範例頁面,在這個頁面中,我們使用了三個 Switch 控制項,這三個 Switch 控制項彼此是互斥的,您可以視為這三個 Switch 控制項的行為,會類似於我們 Windows 程式中的 Radio Button;最後,我們會把您選擇的結果,顯示在最後一個 Label 控制項內。
<?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="XFDataChanged.Views.MainPage"
             Title="Switch 控制項的資料異動偵測與設計方法">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <StackLayout Orientation="Horizontal">
            <Label Text="選項 1"/>
            <Switch IsToggled="{Binding Option1}"/>
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="選項 2"/>
            <Switch IsToggled="{Binding Option2}"/>
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="選項 3"/>
            <Switch IsToggled="{Binding Option3}"/>
        </StackLayout>

        <Label Text="{Binding YourChoice, StringFormat='你選擇的是 {0}'}"/>
    </StackLayout>

</ContentPage>
  • 我們開始進行 ViewModel 的 C# 商業邏輯程式碼的設計,在這裡,我們需要設計三個所綁定 Switch 的 C# Property 屬性物件,當它本身的值有異動的話,我們需要有個相對應的事件方法被呼叫與執行。不過,我們對於這樣的事件方法,它的名稱需要使用指定的命名規格,那就是
    On你的綁定屬性Changed
    其中前的 On 與最後的 Changed 是固定不變的,我們來看個例子,若您的綁定屬性物件為 Option1 ,當使用者在頁面中進行操作,變動了 Option1 的值,這個時候,您的 ViewModel 內的
    OnOption1Changed
    方法,就會被自動呼叫了。
    為了要能夠讓 Switch 的運作表現如同 Radio 的效果,我們同時也設計了 SetOption 方法
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XFDataChanged.ViewModels
{
    using System.ComponentModel;
    using Prism.Events;
    using Prism.Navigation;
    using Prism.Services;
    public class MainPageViewModel : INotifyPropertyChanged, INavigationAware
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public bool Option1 { get; set; }
        public bool Option2 { get; set; }
        public bool Option3 { get; set; }
        public string YourChoice { get; set; }
        private readonly INavigationService _navigationService;

        public MainPageViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;

        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {

        }
        public void OnOption1Changed()
        {
            SetOption(nameof(Option1));
        }
        public void OnOption2Changed()
        {
            SetOption(nameof(Option2));
        }
        public void OnOption3Changed()
        {
            SetOption(nameof(Option3));
        }
        public void OnNavigatedTo(NavigationParameters parameters)
        {
            ResetOptions();
        }

        public void ResetOptions()
        {
            SetOption(nameof(Option1));
        }
        public bool CorrelationAction { get; set; }
        public void SetOption(string choiceOption)
        {
            if (CorrelationAction == true) return;
            CorrelationAction = true;
            switch (choiceOption)
            {
                case nameof(Option1):
                    Option1 = true;
                    Option2 = false;
                    Option3 = false;
                    break;
                case nameof(Option2):
                    Option1 = false;
                    Option2 = true;
                    Option3 = false;
                    break;
                case nameof(Option3):
                    Option1 = false;
                    Option2 = false;
                    Option3 = true;
                    break;
                default:
                    break;
            }
            YourChoice = choiceOption;
            CorrelationAction = false;
        }
    }
}



沒有留言:

張貼留言