XamarinForms 系列課程

特別說明

2017/04/24

簡化 MVVM 的綁定屬性設計

當我們在進行 MVVM 開發設計的時候,在 ViewModel 內需要在 View 中綁定的屬性,都要實作 INotifyPropertyChanged 這個事件;當我們在使用 Prism 開發框架的時候,雖然,提供了一個 BindableBase 類別,來幫助我們實作出 INotifyPropertyChange 事件,可是,在宣告 ViewModel 的屬性時候,還是有些麻煩。
因此,PropertyChanged.Fody 這個 NuGet 套件出現了,它簡化了 ViewModel 的設計。在官方文件中舉個例子:
在這裡,我們僅需要在 ViewModel 類別中,使用了 ImplementPropertyChanged 這個屬性宣告,在整個 ViewModel 內,每個要綁定到 View 中的屬性,僅需要使用 .NET Property 的方式來宣告即可。
[ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}
PropertyChanged.Fody 會在編譯時期,自動為我們產生出相對應的 INotifyPropertyChanged 事件實作,如同底下程式碼所示:
public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
傑克,這是不是太神奇了呀,看到這個套件,我立馬想要來在 Prism 框架中來實作、測試看看。
我建立了一個 View ,這個頁面中,有兩個資料綁定的屬性,與一個命令綁定屬性。
<?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:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="PrismUnityApp7.Views.MainPage"
             Title="MainPage">
    <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
        <Label Text="{Binding Title}" />
        <Entry Text="{Binding entry}" />
        <Button Text="Set" Command="{Binding SetCommand}"/>
    </StackLayout>
</ContentPage>
此時,我的 ViewModel 變得清爽多了;經過執行,還真的可以運作。
    [ImplementPropertyChanged]
    public class MainPageViewModel : INavigationAware
    {
        public string Title { get; set; }
        public string entry { get; set; }

        public DelegateCommand SetCommand { get; set; }

        public MainPageViewModel()
        {
            SetCommand = new DelegateCommand(() =>
            {
                Title = entry;
            });
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatingTo(NavigationParameters parameters)
        {

        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {
            if (parameters.ContainsKey("title"))
                Title = (string)parameters["title"] + " and Prism";
        }
    }
sharp
有興趣的人,可以參可 PropertyChanged.Fody

沒有留言:

張貼留言