WPF 標準コントロールデモアプリ › Button

Button Inputs

Button は WPF で最もよく使われるコマンドトリガーコントロールです。押されると Click イベントが発火し、ICommand インターフェイスを通じたコマンドバインドをサポートします。ButtonBase を継承しており、ClickMode やコマンド関連のプロパティが利用可能です。

概要

WPF の Button コントロールは、デスクトップアプリにおけるユーザーアクションのトリガーとして最も基本的な役割を担います。 ButtonBase を継承し、さらに ContentControl を拡張しているため、Button の中にはテキストだけでなく 画像・アイコン・複雑なパネルなど任意の WPF 要素を配置できます。

MVVM アーキテクチャにおいて特に重要なのが、Command プロパティによる ICommand インターフェイスのサポートです。 コマンドをバインドすると、ICommand.CanExecutefalse を返すたびに WPF が自動でボタンを無効化し、 条件が変化すると再び有効にします。これによりコードビハインドでの有効・無効切り替えロジックが不要になります。

ButtonBase から継承された ClickMode プロパティは、Click イベントがいつ発火するかを制御します。 デフォルトの Release はマウスボタンを離したとき、Press は押し下げた瞬間、 Hover はホバー時に発火します。

IsDefaultIsCancel の 2 つの bool プロパティはダイアログの実装を大幅に簡略化します。 IsDefault="True" で Enter キー、IsCancel="True" で Escape キーとボタンを関連付けられます。

画面キャプチャ

button demo screen

デモしているプロパティ

以下のプロパティが WPF 標準コントロールデモアプリでインタラクティブにデモされています。 アプリ上でリアルタイムに各プロパティを変更してその動作を確認できます。

プロパティ設定値説明
IsCancel bool ダイアログの「キャンセル」ボタンに使用し、Escape キーでの閉じる操作をキーボードのみで完結させたいときに設定します。True にすると、Escape キー押下でこのボタンの Click が発生し、Window.DialogResult = false と組み合わせることで標準的なキャンセル動作を実現できます。注意点として、このプロパティは Window のスコープ内でのみ機能し、UserControl 単体では動作しません。また、同一 Window 内に複数の IsCancel="True" のボタンが存在すると、意図しない競合が発生する可能性があるため、1 つの Window につき 1 つのみ設定してください。
IsDefault bool フォームの「OK」ボタンや「検索」ボタンに使用し、Enter キーでの送信をキーボードのみで完結させたいときに設定します。True にすると、フォーカスを持つ要素が Enter を消費しない場合にこのボタンの Click が発生します。注意点として、1 つの Window につき IsDefault="True" のボタンは 1 つだけにしてください。また、AcceptsReturn="True" に設定された複数行の TextBox にフォーカスがある場合は Enter が TextBox 側で消費されるため、IsDefault ボタンは発火しません。
ClickMode (ButtonBase) Release / Press / Hover Click イベントが発生するタイミングを制御します。Press はゲームコントローラーの入力や、ドラッグ開始のトリガーなど即時反応が求められる場面で使用します。Hover はリボン UI のような、マウスオーバーで展開するメニューボタンに活用できます。デフォルトの Release はマウスボタンを離したときに発火し、押したままキャンセルするユーザー操作(ボタン外へドラッグして離す)に対応した最も標準的な動作です。注意点として、Hover モードは意図せずマウスが通過した際にも発火するため、誤操作を招く可能性があります。用途を限定して慎重に使用してください。
IsPressed (ButtonBase) bool (ReadOnly) カスタム ControlTemplate でボタンの押し込み状態に応じたアニメーションや色変更を実装したいときに使用します。ControlTemplate 内の DataTrigger でこの値を監視することで、押し込み時にスケール縮小や背景色変化などの視覚的フィードバックを与えられます。読み取り専用プロパティのため、外部から直接変更することはできません。注意点として、マウスクリックによる押し込みは確実に反映されますが、Space キーによるキーボード操作では IsPressed が一貫して更新されない場合があり、キーボード専用操作での視覚フィードバックには別の手段(FocusVisualStyle など)を検討してください。
Command (ButtonBase) ICommand MVVM パターンで、コードビハインドを持たずにボタンのアクションを ViewModel に委譲したいときに使用します。ViewModel の ICommand プロパティをバインドすると、CanExecute が false の場合に WPF がボタンを自動で無効化し、CanExecute が変化するたびに UI を更新します。この再評価は CommandManager.RequerySuggested イベントが発火するタイミング(フォーカス移動や入力イベントなど)に行われます。注意点として、CanExecute の処理が重い場合(DB アクセスや時間のかかる計算など)は、UI スレッドが頻繁にブロックされパフォーマンスが低下します。CanExecute は必ず軽量なキャッシュ済みフラグの確認のみにとどめてください。
CommandParameter (ButtonBase) object 同一コマンドを複数のボタンで共有し、ボタンごとに異なる動作をさせたいときに使用します。例えば CommandParameter="{Binding SelectedItem}" のように動的な値をバインドして渡すことも可能です。パラメータを渡すと、Execute および CanExecute の引数として受け取れます。通常の Binding で設定している場合、ソース値が更新されれば CommandParameter もそれに追従して更新されます。一方で、固定値を直接設定している場合や、Mode=OneTime など更新されないバインディングを使っている場合は、自動では変化しません。動的に変わる値を渡す場合は、意図したバインディング モードになっていることを確認してください。

XAML 使用例

MVVM バインドと IsDefault/IsCancel を組み合わせた典型的なダイアログボタンの例です:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
  <Button Content="OK" Width="80" Margin="0,0,8,0"
          IsDefault="True"
          Command="{Binding OkCommand}" />
  <Button Content="キャンセル" Width="80"
          IsCancel="True"
          Command="{Binding CancelCommand}" />
</StackPanel>

<!-- ClickMode の例 -->
<Button Content="ホバーで発火" ClickMode="Hover"
        Command="{Binding HoverCommand}" />

主な使用例

ヒントとベストプラクティス

関連コントロール

ソースコード

このデモ画面のソースコードは GitHub で公開しています。アプリ内の「コード表示」ボタンから各プロパティの実際の XAML を確認できます。

GitHub で Button のソースコードを見る →