XAML フレームワークを使用すると、さまざまな方法でアプリの外観をカスタマイズできます。 スタイルを使用すると、コントロールのプロパティを設定し、それらの設定を再利用して、複数のコントロール間で一貫した外観を実現できます。
WinUI とスタイル
WinUI 2.2 以降では、 WinUI を使用して、UI コンポーネント全体で新しいビジュアル スタイルの更新を提供しました。 UI が最新のスタイルに更新されていない場合は、必ず最新の WinUI NuGet パッケージに更新してください。
WinUI 2.6 以降では、ほとんどのコントロールに新しいスタイルと、必要に応じて以前のコントロール スタイルに戻す新しいバージョン管理システムが提供されています。 新しいスタイルは、Windows のデザインの方向に合わせて使用することをお勧めします。 ただし、シナリオで新しいスタイルをサポートできない場合は、以前のバージョンを引き続き使用できます。
WinUI バージョン 2 を使用するときは、ControlsResourcesVersion
に含める XamlControlsResources
の Application.Resources
プロパティを設定して、スタイルのバージョンを変更できます。
ControlsResourcesVersion
の既定値は、Version2
列挙値です。
この値を Version1
に設定すると、XamlControlsResources
は最新の WinUI バージョンで使用される新しいスタイルではなく、以前のスタイル バージョンを読み込みます。 実行時にこのプロパティを変更することはサポートされておらず、VisualStudio のホット リロード機能は機能しません。ただし、アプリケーションをリビルドすると、コントロール スタイルが変更されます。
<Application.Resources>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls"
ControlsResourcesVersion="Version1"/>
</Application.Resources>
スタイルの基本
スタイルを使用して、再利用可能なリソースにビジュアル プロパティ設定を抽出します。 次に示すのは、BorderBrush、BorderThickness、および Foreground プロパティを設定するスタイルを持つ3つのボタンを示す例です。 スタイルを適用すると、各コントロールでこれらのプロパティを個別に設定しなくても、コントロールを同じように表示できます。
XAML でコントロールのスタイルをインラインで定義することも、再利用可能なリソースとして定義することもできます。 個々のページの XAML ファイル、App.xaml ファイル、または別のリソース ディクショナリ XAML ファイルでリソースを定義します。 リソース ディクショナリ XAML ファイルはアプリ間で共有でき、1 つのアプリで複数のリソース ディクショナリをマージできます。 リソースが定義されている場所によって、使用できるスコープが決まります。 ページ レベルのリソースは、定義されているページでのみ使用できます。 App.xaml とページの両方で同じキーを持つリソースが定義されている場合、ページ内のリソースは App.xaml のリソースをオーバーライドします。 リソースが別のリソース ディクショナリ ファイルで定義されている場合、そのスコープはリソース ディクショナリが参照される場所によって決まります。
スタイル 定義には、TargetType 属性と、1 つ以上の Setter 要素のコレクションが必要です。 TargetType 属性は、スタイルを適用する FrameworkElement 型を指定する文字列です。 TargetType 値には、Windows ランタイムによって定義されている FrameworkElement-derived 型、または参照先アセンブリで使用できるカスタム型を指定する必要があります。 コントロールにスタイルを適用しようとして、コントロールの型が適用しようとしているスタイルの TargetType 属性と一致しない場合は、例外が発生します。
各 Setter 要素には、プロパティ と Valueが必要です。 これらのプロパティ設定は、設定が適用されるコントロール プロパティと、そのプロパティに設定する値を示します。 Setter.Value は、属性またはプロパティ要素の構文を使用して設定できます。 ここでの XAML は、前に示したボタンに適用されたスタイルを示しています。 この XAML では、最初の 2 つの Setter 要素は属性構文を使用しますが、BorderBrush プロパティの最後の Setterでは、プロパティ要素の構文を使用します。 この例では、x:Key 属性 属性を使用しないため、スタイルは暗黙的にボタンに適用されます。 スタイルを暗黙的または明示的に適用する方法については、次のセクションで説明します。
<Page.Resources>
<Style TargetType="Button">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" >
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<StackPanel Orientation="Horizontal">
<Button Content="Button"/>
<Button Content="Button"/>
<Button Content="Button"/>
</StackPanel>
暗黙的または明示的なスタイルを適用する
スタイルをリソースとして定義する場合、コントロールに適用する方法は 2 つあります。
- 暗黙的に、スタイルに対して TargetType のみを指定します。
- 明示的に、TargetType と x:Key 属性を Style の 属性に指定し、明示的なキーを使用する {StaticResource} マークアップ拡張 参照を使用して、ターゲット コントロールの Style プロパティを設定します。
スタイルに x:Key 属性が含まれている場合は、コントロールの Style プロパティをキー付きスタイルに設定することによってのみ、そのスタイルをコントロールに適用できます。 これに対し、x:Key 属性を持たないスタイルは、ターゲット型のすべてのコントロールに自動的に適用され、それ以外の場合は明示的なスタイル設定はありません。
暗黙的なスタイルと明示的なスタイルを示す 2 つのボタンを次に示します。
この例では、最初のスタイルに x:Key 属性 があり、そのターゲットの種類は Buttonです。 最初のボタンの Style プロパティはこのキーに設定されているため、このスタイルは明示的に適用されます。 2 番目のスタイルは、ターゲットの型が Button であり、スタイルに x:Key 属性がないため、2 番目のボタンに暗黙的に適用されます。
<Page.Resources>
<Style x:Key="PurpleStyle" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="Purple"/>
</Style>
<Style TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="25"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Foreground" Value="Green"/>
</Style>
</Page.Resources>
<Grid x:Name="LayoutRoot">
<Button Content="Button" Style="{StaticResource PurpleStyle}"/>
<Button Content="Button"/>
</Grid>
既存のスタイルを使用する
スタイルを維持しやすくし、スタイルの再利用を最適化するために、他のスタイルから継承するスタイルを作成できます。 継承されたスタイルを作成するには、BasedOn プロパティを使用します。 他のスタイルを継承するスタイルは、同じ種類のコントロール、または基本スタイルの対象となる型から派生したコントロールを対象とする必要があります。 たとえば、基本スタイルが ContentControlをターゲットとする場合、このスタイルに基づくスタイルは、ContentControl をターゲットにしたり、ContentControl から派生した型、たとえば Button や ScrollViewerをターゲットにすることができます。 基になっているスタイルで値が設定されていない場合は、基本スタイルから継承されます。 基本スタイルから値を変更するには、基になっているスタイルによってその値がオーバーライドされます。 次の例では、同じ基本スタイルを継承するスタイルを持つ Button と CheckBox を示します。
基本スタイルは ContentControl
<Page.Resources>
<Style x:Key="BasicStyle" TargetType="ContentControl">
<Setter Property="Width" Value="130" />
<Setter Property="Height" Value="30" />
</Style>
<Style x:Key="ButtonStyle" TargetType="Button"
BasedOn="{StaticResource BasicStyle}">
<Setter Property="BorderBrush" Value="Orange" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Foreground" Value="Red" />
</Style>
<Style x:Key="CheckBoxStyle" TargetType="CheckBox"
BasedOn="{StaticResource BasicStyle}">
<Setter Property="BorderBrush" Value="Blue" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Foreground" Value="Green" />
</Style>
</Page.Resources>
<StackPanel>
<Button Content="Button" Style="{StaticResource ButtonStyle}" Margin="0,10"/>
<CheckBox Content="CheckBox" Style="{StaticResource CheckBoxStyle}"/>
</StackPanel>
ツールを使用してスタイルを簡単に操作する
コントロールにスタイルを簡単に適用するには、Microsoft Visual Studio XAML デザイン サーフェイスでコントロールを右クリックし、[スタイルの編集]
軽量スタイル
システム ブラシのオーバーライドは通常、アプリ レベルまたはページ レベルで行われます。どちらの場合も、色のオーバーライドは、そのブラシを参照するすべてのコントロールに影響します。XAML では、多くのコントロールが同じシステム ブラシを参照できます。
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
<SolidColorBrush x:Key="ButtonForeground" Color="MediumSlateBlue"/>
<SolidColorBrush x:Key="ButtonBorderBrush" Color="MediumSlateBlue"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>
PointerOver (マウスがボタンの上にポインターを合わせる)、PointerPressed (ボタンが押されました)、または無効 (ボタンは操作できません) などの状態の場合は
これらのブラシ オーバーライドを app.Resources レベル
コントロールごとのスタイル設定
その他の場合は、1 つのページ上の 1 つのコントロールを変更するだけで、そのコントロールの他のバージョンを変更せずに、特定の方法で表示する必要があります。
<CheckBox Content="Normal CheckBox" Margin="5"/>
<CheckBox Content="Special CheckBox" Margin="5">
<CheckBox.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="CheckBoxForegroundUnchecked"
Color="Purple"/>
<SolidColorBrush x:Key="CheckBoxForegroundChecked"
Color="Purple"/>
<SolidColorBrush x:Key="CheckBoxCheckGlyphForegroundChecked"
Color="White"/>
<SolidColorBrush x:Key="CheckBoxCheckBackgroundStrokeChecked"
Color="Purple"/>
<SolidColorBrush x:Key="CheckBoxCheckBackgroundFillChecked"
Color="Purple"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</CheckBox.Resources>
</CheckBox>
<CheckBox Content="Normal CheckBox" Margin="5"/>
これにより、そのコントロールが存在するページに "Special CheckBox" が 1 つしか表示されません。
カスタム コントロール
独自のカスタム コントロールを組み込みコントロールと視覚的および/または機能的に一致させる際には、暗黙的スタイルと軽量スタイルリソースを使用して、カスタムコンテンツを設計することを検討してください。 リソースを直接使用することも、リソースの新しいエイリアスを作成することもできます。
コントロール リソースを直接使用する
たとえば、Button のようなコントロールを作成する場合は、次のように、コントロールでボタン リソースを直接参照させることができます。
<Style TargetType="local:MyCustomControl">
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
</Style>
コントロールリソースの名前を新しいものに変更する
または、独自のリソースを作成する場合は、これらのカスタム名を既定の軽量スタイル設定リソースに別名を付ける必要があります。
たとえば、カスタム コントロールのスタイルに特別なリソース定義があるとします。
<Style TargetType="local:MyCustomControl">
<Setter Property="Background" Value="{ThemeResource MyCustomControlBackground}" />
<Setter Property="BorderBrush" Value="{ThemeResource MyCustomControlBorderBrush}"/>
</Style>
リソース ディクショナリや主要な定義で、軽量スタイリング リソースを独自のカスタム リソースに接続します。
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
<StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
<StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
<StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
3 つの異なるテーマの変更 (ThemeDictionary
、Default
、Light
) を適切に処理するために、3 回複製された HighContrast
を使用する必要があります。
注意事項
Lightweight スタイル設定リソースを新しいエイリアスに割り当て、また Lightweight スタイル設定リソースを再定義した場合、リソース参照が正しい順序でない場合は、カスタマイズが適用されない可能性があります。 たとえば、ButtonBackground
が見つかる前に検索された場所で MyCustomControlBackground
をオーバーライドした場合、オーバーライドは実行されません。
コントロールの再設定を回避する
WinUI 2.2 以降には、WinUI コントロールとシステム コントロールの両方の新しいスタイルとテンプレートが含まれています。
最新のビジュアル スタイルを最新の状態に保つ最善の方法は、最新の WinUI 2 パッケージを使用し、カスタム スタイルとテンプレート (再テンプレートとも呼ばれます) を回避することです。 スタイルは、アプリ内のコントロール間で一貫して値のセットを適用する便利な方法です。 これを行うときは、最新のスタイルに基づいてください。
WinUI スタイル (Windows.UI.Xaml.Controls
名前空間) を使用するシステム コントロールの場合は、BasedOn="{StaticResource Default<ControlName>Style}"
を設定します。ここで、<ControlName>
はコントロールの名前です。 例えば次が挙げられます。
<Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextBoxStyle}">
<Setter Property="Foreground" Value="Blue"/>
</Style>
WinUI 2 コントロール (Microsoft.UI.Xaml.Controls
名前空間) の場合、既定のスタイルはメタデータで定義されているため、BasedOn
は省略します。
派生コントロール
既存の XAML コントロールからカスタム コントロールを派生させる場合、既定では WinUI 2 スタイルは取得されません。 WinUI 2 スタイルを適用するには:
- TargetType をカスタム コントロールに設定して、新しい スタイル を作成します。
- スタイルは、派生元のコントロールの既定のスタイルに基づいて指定します。
この一般的なシナリオの 1 つは、の新しいコントロールを ContentDialogから派生することです。 この例では、カスタム ダイアログに DefaultContentDialogStyle
適用する新しいスタイルを作成する方法を示します。
<ContentDialog
x:Class="ExampleApp.SignInContentDialog"
... >
<ContentDialog.Resources>
<Style TargetType="local:SignInContentDialog" BasedOn="{StaticResource DefaultContentDialogStyle}"/>
...
</ContentDialog.Resources>
<!-- CONTENT -->
</ContentDialog>
template プロパティ
スタイル セッターは、コントロールの Template プロパティに使用できます。実際、これは一般的な XAML スタイルとアプリの XAML リソースの大部分を構成します。 これについては、「コントロール テンプレート
Windows developer