XAMLで始めるWPF入門:Style関連の覚書

コンピュータ

XAMLは基本的に静的にコントロールをレイアウトしますが、Styleを用意しておくと、
あとから動的に生成されるコントロールにも同じ見た目や振る舞いを一括適用できます。
(既定のプロパティ値を差し替えたり、イベントの配線をまとめたりできます)

主な機能

  • Setter依存関係プロパティ(DP)添付プロパティ の値を設定(Value="{Binding ...}" のようにバインディングも可)
  • EventSetter … ルーティングイベントとイベントハンドラを接続(例:MouseDoubleClick → ハンドラ)
  • Trigger … 状態に応じて Setter を切り替え(見た目の切替に限定。無理に乱用しない)
    ※必要に応じて Trigger / DataTrigger / MultiTrigger / MultiDataTrigger が使えます

適用の範囲

  • 暗黙スタイル(Implicit Style)TargetType だけを指定し、x:Key を付けない。
    同じリソーススコープ内の該当型すべてに自動適用されます。
  • 明示スタイル(Explicit Style)x:Key を付けて定義し、使いたいコントロール側で
    Style="{StaticResource YourStyleKey}" のように明示参照します。

x:Name でStyle側から個体指定はできません。個別に当てたい場合は「明示スタイル」を作り、コントロール側で参照させます。

優先順位(簡略)

ローカル値 > Trigger の Setter > Style の Setter > 既定値
コントロールに直接書いた値(ローカル値)が最優先で、Styleの値はそれに上書きされます。

サンプル

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Style Memo" Width="480" Height="260">

  <Window.Resources>
    <!-- 1) 暗黙スタイル:このWindow内のButtonすべてに適用 -->
    <Style TargetType="Button">
      <Setter Property="Padding" Value="12,6"/>
      <Setter Property="FontWeight" Value="SemiBold"/>
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="Background" Value="#FFF3F9FF"/>
        </Trigger>
      </Style.Triggers>
    </Style>

    <!-- 2) 明示スタイル:ListView の行コンテナにだけ適用 -->
    <Style x:Key="ListRowStyle" TargetType="ListViewItem">
      <Setter Property="Padding" Value="6"/>
      <EventSetter Event="MouseDoubleClick" Handler="OnRowDoubleClick"/>
      <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
          <Setter Property="FontWeight" Value="Bold"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </Window.Resources>

  <DockPanel Margin="12">
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="0 0 0 8">
      <Button Content="OK"/>
      <Button Content="Cancel" Margin="8 0 0 0"/>
    </StackPanel>

    <ListView ItemContainerStyle="{StaticResource ListRowStyle}">
      <ListViewItem>みかん</ListViewItem>
      <ListViewItem>りんご</ListViewItem>
      <ListViewItem>パイナップル</ListViewItem>
    </ListView>
  </DockPanel>
</Window>

ポイントまとめ

  • SetterはDP/添付プロパティに効く(CLRプロパティは不可)
  • Triggerは見た目の切替専用。処理は EventSetter → コードビハインド → VMメソッド
  • 個別適用は x:Key を付けてコントロール側で参照する

いつ使う

ListView では ItemContainerStyle は避けて通れない
それ以外ではなるべく使わないのが個人的方針。
Style は基本的に 依存関係プロパティ(DP) が対象で、データバインディング前提の“見た目・性質の既定値合わせ”に向く。
万能ではない(ロジック実行は不可)。処理は EventSetter → コードビハインド → VM メソッド で受ける。

  • 使う場面:ListView の行コンテナ(選択・フォーカス・Padding・配線)、共通の見た目既定値、軽い状態による見た目切替(IsSelected など)
  • 避ける場面:複雑な分岐・手続き・外部I/O。Trigger で頑張らず、処理はコード側に寄せる

コメント