天天看點

第八章:代碼和XAML協調一緻(1)傳遞參數

代碼檔案和XAML檔案始終作為一對存在。 這兩個檔案互相補充。 盡管被稱為XAML的“代碼隐藏”檔案,但代碼在處理應用程式的更活躍和互動式部分時經常顯得尤為突出。 這意味着代碼隐藏檔案必須能夠像在代碼中執行個體化的對象一樣輕松地引用XAML中定義的元素。 同樣,XAML中的元素必須能夠觸發在基于代碼的事件處理程式中處理的事件。 這就是本章的全部内容。

但首先,我們來探索一些用于在XAML檔案中執行個體化對象的不尋常技術。

傳遞參數

當您運作包含XAML檔案的應用程式時,XAML檔案中的每個元素都會通過調用相應類或結構的無參數構造函數來執行個體化。 加載過程通過設定屬性值的屬性來繼續初始化結果對象。 這似乎很有道理。 但是,使用XAML的開發人員有時需要使用需要參數的構造函數或通過調用靜态建立方法來執行個體化對象。 這些需求通常不涉及API本身,而是涉及XAML檔案引用的與API互動的外部資料類。

2009年的XAML規範引入了一個x:Arguments元素和一個x:FactoryMethod來表達這些情況,而Xamarin.Forms支援它們。 這些技術通常不會在一般情況下使用,但您應該看看它們在需要時如何工作。

帶參數的構造函數

要将參數傳遞給XAML中元素的構造函數,元素必須分隔為開始标簽和結束标簽。 使用x:Arguments開始和結束标簽跟随元素的開始标記。 在那些x:Arguments标記内,包含一個或多個構造函數參數。

但是,如何指定常見類型的多個參數,例如double或int? 你用逗号分析參數嗎?

不。每個參數必須用開始和結束标記分隔。 幸運的是,XAML 2009規範定義了常用基本類型的XML元素。 您可以使用這些标簽來闡明元素的類型,在OnPlatform中指定泛型類型,或者分隔構造函數參數。 這是Xamarin.Forms支援的完整集合。 注意它們複制.NET類型名稱而不是C#類型名稱:

 x:Object
 x:Boolean
 x:Byte
 x:Int16
 x:Int32
 x:Int64
 x:Single
 x:Double
 x:Decimal
 x:Char
 x:String
 x:TimeSpan
 x:Array
 x:DateTime (由Xamarin.Forms支援,但不是XAML 2009規範)           

你會很難找到所有這些的用途,但你一定會發現其中一些用途。

ParameteredConstructorDemo示例示範了如何使用x:Arguments,其中包含由x:Double标簽分隔的參數,使用Color結構的三個不同構造函數。 具有三個參數的結構需要紅色,綠色和藍色值,範圍從0到1.帶有四個參數的構造函數添加一個alpha通道作為第四個參數(在此設定為0.5),以及帶有a的構造函數 單參數表示從0(黑色)到1(白色)的灰色陰影:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ParameteredConstructorDemo.ParameteredConstructorDemoPage">
    <StackLayout>
        <BoxView WidthRequest="100"
                 HeightRequest="100"
                 HorizontalOptions="Center"
                 VerticalOptions="CenterAndExpand">
            <BoxView.Color>
                <Color>
                    <x:Arguments>
                        <x:Double>1</x:Double>
                        <x:Double>0</x:Double>
                        <x:Double>0</x:Double>
                    </x:Arguments>
                </Color>
            </BoxView.Color>
        </BoxView>
        <BoxView WidthRequest="100"
                 HeightRequest="100"
                 HorizontalOptions="Center"
                 VerticalOptions="CenterAndExpand">
            <BoxView.Color>
                <Color>
                    <x:Arguments>
                        <x:Double>0</x:Double>
                        <x:Double>0</x:Double>
                        <x:Double>1</x:Double>
                        <x:Double>0.5</x:Double>
                    </x:Arguments>
                </Color>
            </BoxView.Color>
        </BoxView>
        <BoxView WidthRequest="100"
                 HeightRequest="100"
                 HorizontalOptions="Center"
                 VerticalOptions="CenterAndExpand">
            <BoxView.Color>
                <Color>
                    <x:Arguments>
                        <x:Double>0.5</x:Double>
                    </x:Arguments>
                </Color>
            </BoxView.Color>
        </BoxView>
    </StackLayout>
</ContentPage>           

x:Arguments标簽中的元素數量以及這些元素的類型必須與類或結構的構造函數之一比對。 這是結果:

第八章:代碼和XAML協調一緻(1)傳遞參數

藍色的BoxView在淺色背景下是淺色的,在深色背景下是暗色的,因為它透明度為50%,讓背景顯示出來。

我可以從XAML調用方法嗎?

有一次,這個問題的答案是“不要太荒謬”,但現在它是一個合格的“是”。不過,不要太激動。 您可以在XAML中調用的唯一方法是傳回與定義方法的類(或結構)相同類型的對象(或值)的方法。 這些方法必須是公共的和靜态的。 它們有時被稱為建立方法或工廠方法。 您可以通過使用x:FactoryMethod屬性及其使用x:Arguments元素的參數指定方法名稱,通過調用其中一個方法來執行個體化XAML中的元素。

Color結構定義了七個傳回Color值的靜态方法,是以這些方法是合格的。 這個XAML檔案使用了其中的三個:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FactoryMethodDemo.FactoryMethodDemoPage">
 
    <StackLayout>
        <BoxView WidthRequest="100"
                 HeightRequest="100"
                 HorizontalOptions="Center"
                 VerticalOptions="CenterAndExpand">
            <BoxView.Color>
                <Color x:FactoryMethod="FromRgb">
                    <x:Arguments>
                        <x:Int32>255</x:Int32>
                        <x:Int32>0</x:Int32>
                        <x:Int32>0</x:Int32>
                    </x:Arguments>
                </Color>
            </BoxView.Color>
        </BoxView>
        <BoxView WidthRequest="100"
                 HeightRequest="100"
                 HorizontalOptions="Center"
                 VerticalOptions="CenterAndExpand">
            <BoxView.Color>
                <Color x:FactoryMethod="FromRgb">
                    <x:Arguments>
                        <x:Double>0</x:Double>
                        <x:Double>1.0</x:Double>
                        <x:Double>0</x:Double>
                    </x:Arguments>
                </Color>
            </BoxView.Color>
        </BoxView>
        <BoxView WidthRequest="100"
                 HeightRequest="100"
                 HorizontalOptions="Center"
                 VerticalOptions="CenterAndExpand">
            <BoxView.Color>
                <Color x:FactoryMethod="FromHsla">
                    <x:Arguments>
                        <x:Double>0.67</x:Double>
                        <x:Double>1.0</x:Double>
                        <x:Double>0.5</x:Double>
                        <x:Double>1.0</x:Double>
                    </x:Arguments>
                </Color>
            </BoxView.Color>
        </BoxView>
    </StackLayout>
</ContentPage>           

這裡調用的前兩個靜态方法都被命名為Color.FromRgb,但是x:Arguments标簽中的元素類型區分了範圍從0到255的int參數和範圍從0到1的雙參數。第三個 是Color.FromHsla方法,它根據色調,飽和度,亮度和alpha分量建立一個Color值。 有趣的是,這是通過使用Xamarin.Forms API從XAML檔案中的HSL值定義Color值的唯一方法。 這是結果:

第八章:代碼和XAML協調一緻(1)傳遞參數

繼續閱讀