Xamarin.Forms でのスタイルの継承
スタイルを他のスタイルから継承することで、重複を減らし、再利用が可能になります。
XAML でのスタイルの継承
スタイルの継承は、Style.BasedOn
プロパティを既存の Style
プロパティに設定することによって実行されます。 XAML の場合は、BasedOn
プロパティを (以前に作成した Style
を参照する) StaticResource
マークアップ拡張機能に設定することで、これが実現されます。 C# の場合には、BasedOn
プロパティを Style
インスタンスに設定することによって実現されます。
基本スタイルから継承するスタイルには、新しいプロパティの Setter
インスタンスを含めることができます。あるいは、このインスタンスで基本スタイルをオーバーライドできます。 さらに、基本スタイルを継承するスタイルは、同じ型、または基本スタイルの対象となる型から派生した型を対象とする必要があります。 たとえば、基本スタイルが View
インスタンスをターゲットしている場合、その基本スタイルに基づくスタイルは View
インスタンスをターゲットするか、Label
や Button
など、View
クラスから 派生した型をターゲットにすることができます。
次のコードで、 XAML ページでの明示的なスタイルの継承を示します。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.StyleInheritancePage" Title="Inheritance" IconImageSource="xaml.png">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="baseStyle" TargetType="View">
<Setter Property="HorizontalOptions"
Value="Center" />
<Setter Property="VerticalOptions"
Value="CenterAndExpand" />
</Style>
<Style x:Key="labelStyle" TargetType="Label"
BasedOn="{StaticResource baseStyle}">
...
<Setter Property="TextColor" Value="Teal" />
</Style>
<Style x:Key="buttonStyle" TargetType="Button"
BasedOn="{StaticResource baseStyle}">
<Setter Property="BorderColor" Value="Lime" />
...
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="0,20,0,0">
<Label Text="These labels"
Style="{StaticResource labelStyle}" />
...
<Button Text="So is the button"
Style="{StaticResource buttonStyle}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
baseStyle
は View
インスタンスをターゲットし、HorizontalOptions
および VerticalOptions
プロパティを設定します。 baseStyle
は、どのコントロールにも直接設定されません。 代わりに、labelStyle
と buttonStyle
がそれを継承し、追加のバインド可能なプロパティ値を設定します。 その後、labelStyle
および buttonStyle
は、Style
プロパティを設定することで、Label
および Button
のインスタンスに適用されます。 これで、次のスクリーンショットのような結果になります。
Note
暗黙的なスタイルを明示的なスタイルから派生させることはできますが、明示的なスタイルを暗黙的なスタイルから派生させることはできません。
継承チェーンの尊重
スタイルは、ビュー階層内の同じレベル以上のスタイルからのみ継承できます。 これは、次のことを意味します。
- アプリケーション レベルのリソースは、他のアプリケーション レベルのリソースからのみ継承できます。
- ページ レベルのリソースは、アプリケーション レベルのリソースや、その他のページ レベルのリソースから継承できます。
- コントロール レベルのリソースは、アプリケーション レベルのリソース、ページ レベルのリソース、およびその他のコントロール レベルのリソースから継承できます。
この継承チェーンを、次のコード例の中に示します。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.StyleInheritancePage" Title="Inheritance" IconImageSource="xaml.png">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="baseStyle" TargetType="View">
...
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Padding="0,20,0,0">
<StackLayout.Resources>
<ResourceDictionary>
<Style x:Key="labelStyle" TargetType="Label" BasedOn="{StaticResource baseStyle}">
...
</Style>
<Style x:Key="buttonStyle" TargetType="Button" BasedOn="{StaticResource baseStyle}">
...
</Style>
</ResourceDictionary>
</StackLayout.Resources>
...
</StackLayout>
</ContentPage.Content>
</ContentPage>
この例で、labelStyle
および buttonStyle
はコントロール レベルのリソースですが、baseStyle
はページ レベルのリソースです。 ただし、labelStyle
と buttonStyle
が baseStyle
からの継承を行なう一方で、ビュー階層内のそれぞれの場所が理由で、baseStyle
が labelStyle
もしくは buttonStyle
からの継承を行なうことはできません。
C# でのスタイルの継承
C# の場合のページを次のコード例で示します。ここでは、必要なコントロールの Style
プロパティに、Style
インスタンスが直接割り当てられています。
public class StyleInheritancePageCS : ContentPage
{
public StyleInheritancePageCS ()
{
var baseStyle = new Style (typeof(View)) {
Setters = {
new Setter {
Property = View.HorizontalOptionsProperty, Value = LayoutOptions.Center },
...
}
};
var labelStyle = new Style (typeof(Label)) {
BasedOn = baseStyle,
Setters = {
...
new Setter { Property = Label.TextColorProperty, Value = Color.Teal }
}
};
var buttonStyle = new Style (typeof(Button)) {
BasedOn = baseStyle,
Setters = {
new Setter { Property = Button.BorderColorProperty, Value = Color.Lime },
...
}
};
...
Content = new StackLayout {
Children = {
new Label { Text = "These labels", Style = labelStyle },
...
new Button { Text = "So is the button", Style = buttonStyle }
}
};
}
}
baseStyle
は View
インスタンスをターゲットし、HorizontalOptions
および VerticalOptions
プロパティを設定します。 baseStyle
は、どのコントロールにも直接設定されません。 代わりに、labelStyle
と buttonStyle
がそれを継承し、追加のバインド可能なプロパティ値を設定します。 その後、labelStyle
および buttonStyle
は、Style
プロパティを設定することで、Label
および Button
のインスタンスに適用されます。