06 扩充标签- 静态& 资源档使用

作者: 归零者 分类: UI学习 发布时间: 2017-09-06 13:35



学习目标

  • x:Static – XAML 类C# 再来一发
  • Resource – StaticResource – 可重复利用的扩充标签

    Xamarin一直积极的要让XAML做一些C#能做的事情,例如这一章节要讲的扩充标签(markup extensions)。

    在C#内要指派给triangle.Angle1值的话可以如下:

    triangle.Angle1 = 45;

    triangle.Angle1 = 180 * radians / Math.PI;

    triangle.Angle1 = angles[i];

    triangle.Angle1 = animator.GetCurrentAngle();

    只要结果回传 是浮点数( double )就好。

    但你没办法在XAML内写上这种鬼东西的:

    <triangle.Angle1>

        180 * radians / Math.PI

    </triangle.Angle1>

    让哥怀念起MVC 的Razor 真是方便…

     鉴于以上原因,Xamarin在XAML 2009规格内定义了扩充标签(markup extensions),让我们在编写XAML时能有更多的弹性。

    扩充标签有以下三大类型:

    1.前面带x :的扩充标签:

  • x : Static
  • x : Reference
  • x : Type
  • x : Null
  • x : Array

    2. 跟资料面有关系的:

  • StaticResource
  • DynamicResource
  • Binding

    3. 或是给RelativeLayout 用的:

  • ConstrainExpression


    从第一个x:Static 来介绍-

    X:静

    先来看一下这Label: 

<Label
Text="Just some text"


BackgroundColor="Accent"


TextColor="Black"


FontAttributes="Italic"


VerticalOptions="Center"


HorizontalTextAlignment="Center"
/>

 


Label的五个属性值都是字串 
其实执行时,这些字串都是先透过C #的TryParse (转换)后才给予他们真正的意义。

可以使用x:Static改写成: 

<Label
Text="Just some text"


BackgroundColor="{x:Static Color.Accent}"


TextColor="{x:Static Color.Black}"


FontAttributes="{x:Static FontAttributes.Italic}"

VerticalOptions="{x:Static LayoutOptions.Center}"


HorizontalTextAlignment="{x:Static TextAlignment.Center}"
/>

 


这两个比较下来很清楚的知道  x:Static  的功能,就是在XAML内使用C#的变数。

但以上的改写其实没啥意义…

介绍有用一点的程式,我们可以先在C#定义好变数和其值: 

namespace SharedStatics
{

static
class
AppConstants
{

public
static
Color
LightBackground = Color.Yellow;

public
static
Color
DarkForeground = Color.Blue;

public
static
double
NormalFontSize = 18;

public
static
double
TitleFontSize = 1.4 * NormalFontSize;

public
static
double
ParagraphSpacing = 10;

public
const
FontAttributes
Emphasis = FontAttributes.Italic;

public
const
FontAttributes
TitleAttribute = FontAttributes.Bold;

public
const
TextAlignment
TitleAlignment = TextAlignment.Center;
}
}

 


接着在XAML 内使用其变数: 

<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"

xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"


xmlns:local="clr-namespace:SharedStatics"


x:Class="SharedStatics.SharedStaticsPage"


BackgroundColor="{x:Static local:AppConstants.LightBackground}">


<StackLayout
Padding="10, 0"


Spacing="{x:Static local:AppConstants.ParagraphSpacing}">

 


要注意的是在ContentPage内有先引用xmlns:local=”clr-namespace:SharedStatics”

另外,因为  MathEnviroment 在.NET System namespace内有定义,可以在引用namespace后使用其静态变数如Math.PI: 

<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"


xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"


xmlns:sys="clr-namespace:System;assembly=mscorlib"


x:Class="SystemStatics.SystemStaticsPage">


<!--Math.PI-->

<Button
Text=" Button with &#x03C0; border width "


BorderWidth="{x:Static sys:Math.PI}"


HorizontalOptions="Center"


VerticalOptions="CenterAndExpand">


<Button.BackgroundColor>

<OnPlatform
x:TypeArguments="Color"
Android="#404040"
/>

</Button.BackgroundColor>


<Button.BorderColor>

<OnPlatform
x:TypeArguments="Color"
Android="White"
WinPhone="Black"
/>

</Button.BorderColor>


</Button>


<Label
VerticalOptions="CenterAndExpand"

HorizontalTextAlignment="Center"

FontSize="Medium">


<!--Environment.NewLine-->

<Label.FormattedText>

<FormattedString>

<Span
Text="Three lines of text"
/>

<Span
Text="{x:Static sys:Environment.NewLine}"
/>

<Span
Text="separated by"
/>

<Span
Text="{x:Static sys:Environment.NewLine}"
/>

<Span
Text="Environment.NewLine"
FontSize="Medium"
FontAttributes="Italic"
/>

<Span
Text=" strings"
/>

</FormattedString>

</Label.FormattedText>


</Label>

</StackLayout>
</ContentPage>

 


执行结果:


  1. Resource dictionaries

    上面看到C#内建立全域变数,并在XAML内使用其值的范例。

    Xamarin也想将这件事情搬来XAML做…所以提供了<ResourceDictionary>这样的扩充标签,让我们在XAML内建立共用的变数资源

    使用Resource dictionaries时又分成StaticResource和DynamicResource,差在一个读取静态XAML dictionaries,后一个由.cs指派dictionaries时使用。

    StaticResource

    假设你要在StackLayout内建立三个相似的Button,你可能会这么写: 

    <StackLayout>
    
    
    <!--First Button-->
    
    <Button
    Text=" Carpe diem "
    
    
    HorizontalOptions="Center"
    
    VerticalOptions="CenterAndExpand"
    
    
    BorderWidth="3"
    
    
    TextColor="Red"
    
    FontSize="Large">
    
    
    <Button.BackgroundColor>
    
    <OnPlatform
    x:TypeArguments="Color"
    Android="#404040"
    />
    
    </Button.BackgroundColor>
    
    
    <Button.BorderColor>
    
    <OnPlatform
    x:TypeArguments="Color"
    Android="White"
    WinPhone="Black"
    />
    
    </Button.BorderColor>
    
    </Button>
    
    
    <!--Second Button-->
    
    <Button
    Text=" Sapere aude "
    
    HorizontalOptions="Center"
    
    VerticalOptions="CenterAndExpand"
    
    
    BorderWidth="3"
    
    
    TextColor="Red"
    
    
    FontSize="Large">
    
    
    <Button.BackgroundColor>
    
    <OnPlatform
    x:TypeArguments="Color"
    Android="#404040"
    />
    
    </Button.BackgroundColor>
    
    
    <Button.BorderColor>
    
    <OnPlatform
    x:TypeArguments="Color"
    Android="White"
    WinPhone="Black"
    />
    
    </Button.BorderColor>
    
    </Button>
    
    
    <!--Third Button-->
    
    <Button
    Text=" Discere faciendo "
    
    
    HorizontalOptions="Center"
    
    
    VerticalOptions="CenterAndExpand"
    
    
    BorderWidth="3"
    
    TextColor="Red"
    
    
    FontSize="Large">
    
    
    <Button.BackgroundColor>
    
    <OnPlatform
    x:TypeArguments="Color"
    Android="#404040"
    />
    
    </Button.BackgroundColor>
    
    
    <Button.BorderColor>
    
    <OnPlatform
    x:TypeArguments="Color"
    Android="White"
    WinPhone="Black"
    />
    
    </Button.BorderColor>
    
    </Button>
    
    </StackLayout>

     



很多属性的值是  重复 的,执行结果如下:


此时我们就能在(Visual Elements).Resource内撰写  <ResourceDictionoary>标签,来制作  可重复利用 的资源档: 

<ContentPage.Resources>

<ResourceDictionary>

<LayoutOptions
x:Key="horzOptions">Center</LayoutOptions>

<LayoutOptions
x:Key="vertOptions"
Alignment="Center"
Expands="True"
/>

<x:Double
x:Key="borderWidth">3</x:Double>

<Color
x:Key="textColor">Red</Color>

<OnPlatform
x:Key="backgroundColor"
x:TypeArguments="Color"
Android="#404040"
/>

<OnPlatform
x:Key="borderColor"
x:TypeArguments="Color"
Android="White"
WinPhone="Black"
/>

<x:String
x:Key="fontSize">Large</x:String>

</ResourceDictionary>

</ContentPage.Resources>

 

要注意ResourceDictionary内每个资源都有x:Key这属性,且同一层级下的x:Key不能重复

接着使用StaticResource改写属性: 

<Button
Text=" Discere faciendo "


HorizontalOptions="{StaticResource horzOptions}"


VerticalOptions="{StaticResource vertOptions}"


BorderWidth="{StaticResource borderWidth}"


TextColor="{StaticResource textColor}"

BackgroundColor="{StaticResource backgroundColor}"

BorderColor="{StaticResource borderColor}"


FontSize="{StaticResource fontSize}"
/>

 

 

这样三颗Button重复的属性值,我们只要在ResourceDictionary写一次就能使用,当然也便于维护。

Resource可以储存各种物件,像是把一颗Button放进去: 

<ContentPage.Resources>

<ResourceDictionary>

<Button
x:Key="button"


Text="Shared Button?"


HorizontalOptions="Center"


VerticalOptions="CenterAndExpand"

FontSize="Large"
/>

</ResourceDictionary>

</ContentPage.Resources>

 

 

但是!!!同一颗按钮是不能出现两次的…所以以下写法会出错:

<StackLayout>

<StaticResourceExtension
Key="button"
/>

<StaticResourceExtension
Key="button"
/>

</StackLayout>

 

 

关于这种多个元件需要同样的  属性 时,会在12章  Style  有说明。

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

说点什么

avatar
  Subscribe  
提醒
跳至工具栏