天天看點

第七章:XAML vs. code(3)

屬性元素文法

這裡有一些C#與第4章中的FramedText代碼相似。在一個語句中,它執行個體化一個Frame和一個Label,并将Label設定為Frame的Content屬性:

new Frame
{
    OutlineColor = Color.Accent,
    HorizontalOptions = LayoutOptions.Center,
    VerticalOptions = LayoutOptions.Center,
    Content = new Label
    {
        Text = "Greetings, Xamarin.Forms!"
    }
};           

但是當你開始在XAML中複制它時,你可能會在設定Content屬性的時候變得有點困難:

<Frame OutlineColor="Accent"
       HorizontalOptions="Center"
       VerticalOptions="Center"
       Content=" what goes here? " />           

如何将Content屬性設定為整個Label對象?

這個問題的解決方案是XAML文法的最基本特征。 第一步是将Frame标簽分成開始标簽和結束标簽:

<Frame OutlineColor="Accent"
       HorizontalOptions="Center"
       VerticalOptions="Center">
 
</Frame>           

在這些标簽中,添加兩個由元素(Frame)和您想要設定的屬性(Content)組成的标簽,并添加一個句點:

<Frame OutlineColor="Accent"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Frame.Content>
 
    </Frame.Content>
</Frame>           

現在把标簽放在這些标簽中:

<Frame OutlineColor="Accent"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Frame.Content>
        <Label Text="Greetings, Xamarin.Forms!" />
    </Frame.Content>
</Frame>           

該文法是如何将Label設定為Frame的Content屬性。

您可能想知道這個XAML功能是否違反了XML文法規則。 它不是。 這段時間在XML中沒有特殊含義,是以Frame.Content是一個完全有效的XML标簽。 然而,XAML強加了關于這些标簽的規則:Frame.Content标簽必須出現在Frame标簽中,并且不能在Frame.Content标簽中設定屬性。 設定為Content屬性的對象顯示為這些标記的XML内容。

一旦引入了這個文法,就需要一些術語。 在上面顯示的最終XAML代碼片段中:

  • 架構和标簽是用XML元素表示的C#對象。 它們被稱為對象元素。
  • OutlineColor,HorizontalOptions,VerticalOptions和Text是作為XML屬性提供的C#屬性。 他們被稱為财産屬性。
  • Frame.Content是以XML元素表示的C#屬性,是以稱為屬性元素。

屬性元素在現實生活中很常見。 本章和未來章節中将會看到許多示例,您很快就會發現屬性元素成為您使用XAML的第二本質。 但要小心:有時開發人員必須記得太多,以至于我們忘記了基本知識。 即使在您使用XAML一段時間後,您可能會遇到這樣的情況,即似乎無法将特定對象設定為特定屬性。 解決方案通常是一個屬性元素。

您還可以對簡單的屬性使用屬性元素文法,例如:

<Frame HorizontalOptions="Center">
    <Frame.VerticalOptions>
        Center
    </Frame.VerticalOptions>
    <Frame.OutlineColor>
        Accent
    </Frame.OutlineColor>
    <Frame.Content>
        <Label>
            <Label.Text>
                Greetings, Xamarin.Forms!
            </Label.Text>
        </Label>
    </Frame.Content>
</Frame>           

現在,Frame的VerticalOptions和OutlineColor屬性以及Label的Text屬性都已成為屬性元素。 這些屬性的值始終是不帶引号的屬性元素的内容。

當然,将這些屬性定義為屬性元素沒有多大意義。 這是不必要的,一切都很冗長。 但它的工作原理應該如此。

讓我們進一步:不是将HorizontalOptions設定為“Center”(對應于靜态屬性LayoutOptions.Center),您可以将HorizontalOptions表示為屬性元素,并将其設定為LayoutOptions值并設定其各個屬性:

<Frame>
    <Frame.HorizontalOptions>
        <LayoutOptions Alignment="Center"
                       Expands="False" />
    </Frame.HorizontalOptions>
    <Frame.VerticalOptions>
        Center
    </Frame.VerticalOptions>
    <Frame.OutlineColor>
        Accent
    </Frame.OutlineColor>
    <Frame.Content>
       <Label>
            <Label.Text>
                Greetings, Xamarin.Forms!
            </Label.Text>
        </Label>
    </Frame.Content>
</Frame>```

您還可以将LayoutOptions的這些屬性表示為屬性元素:
           
<Frame.HorizontalOptions>
    <LayoutOptions>
         <LayoutOptions.Alignment>
             Center
         </LayoutOptions.Alignment>
         <LayoutOptions.Expands>
             False
           </LayoutOptions.Expands>
    </LayoutOptions>
</Frame.HorizontalOptions>
           

`

您不能将屬性設定為屬性屬性和屬性元素。 這是設定屬性兩次,這是不允許的。 請記住,沒有其他内容可以出現在屬性元素标簽中。 設定為屬性的值始終是這些标記的XML内容。

現在你應該知道如何在XAML中使用StackLayout。 首先将Children屬性表示為屬性元素StackLayout.Children,然後将StackLayout的子元素作為屬性元素标記的XML内容。 下面是一個例子,第一個StackLayout的每個孩子都是另一個具有水準方向的StackLayout:

<StackLayout>
    <StackLayout.Children>
        <StackLayout Orientation="Horizontal">
            <StackLayout.Children>
                <BoxView Color="Red" />
                <Label Text="Red"
                            VerticalOptions="Center" />
            </StackLayout.Children>
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <StackLayout.Children>
                <BoxView Color="Green" />
                <Label Text="Green"
                       VerticalOptions="Center" />
            </StackLayout.Children>
         </StackLayout>
         <StackLayout Orientation="Horizontal">
             <StackLayout.Children>
                 <BoxView Color="Blue" />
                 <Label Text="Blue"
                        VerticalOptions="Center" />
             </StackLayout.Children>
         </StackLayout>
    </StackLayout.Children>
</StackLayout>           

每個水準的StackLayout都有一個帶有顔色的BoxView和一個帶有該顔色名稱的标簽。

當然,這裡的重複标記看起來相當可怕! 如果你想要顯示16種顔色怎麼辦? 還是140? 一開始可能會有很多複制和粘貼成功,但如果您需要稍微改進視覺效果,那麼您的狀态會很糟糕。 在代碼中,您可以在循環中執行此操作,但XAML沒有此功能。

當标記威脅過于重複時,您可以随時使用代碼。 在XAML中定義一些使用者界面而在代碼中定義一些使用者界面是非常合理的。 但是還有其他的解決方案,你會在後面的章節中看到。

繼續閱讀