WPF 標準コントロールデモアプリ › Button
Button Inputs
Button は WPF で最もよく使われるコマンドトリガーコントロールです。押されると Click イベントが発火し、ICommand インターフェイスを通じたコマンドバインドをサポートします。ButtonBase を継承しており、ClickMode やコマンド関連のプロパティが利用可能です。
概要
WPF の Button コントロールは、デスクトップアプリにおけるユーザーアクションのトリガーとして最も基本的な役割を担います。
ButtonBase を継承し、さらに ContentControl を拡張しているため、Button の中にはテキストだけでなく
画像・アイコン・複雑なパネルなど任意の WPF 要素を配置できます。
MVVM アーキテクチャにおいて特に重要なのが、Command プロパティによる ICommand インターフェイスのサポートです。
コマンドをバインドすると、ICommand.CanExecute が false を返すたびに WPF が自動でボタンを無効化し、
条件が変化すると再び有効にします。これによりコードビハインドでの有効・無効切り替えロジックが不要になります。
ButtonBase から継承された ClickMode プロパティは、Click イベントがいつ発火するかを制御します。
デフォルトの Release はマウスボタンを離したとき、Press は押し下げた瞬間、
Hover はホバー時に発火します。
IsDefault と IsCancel の 2 つの bool プロパティはダイアログの実装を大幅に簡略化します。
IsDefault="True" で Enter キー、IsCancel="True" で Escape キーとボタンを関連付けられます。
画面キャプチャ
デモしているプロパティ
以下のプロパティが 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}" />
主な使用例
- ダイアログの OK/キャンセル — IsDefault と IsCancel を使ってキーボード操作に対応したダイアログボタンを実装します。
- フォームの送信 — IsDefault="True" を設定することで Enter キーによるフォーム送信を実現します。
- MVVM コマンドバインド — Command プロパティで ViewModel の ICommand をバインドし、CanExecute による自動有効/無効を活用します。
- リッチコンテンツボタン — ContentControl の特性を活かし、アイコン+テキストや複数行のコンテンツを持つボタンを作成します。
- ツールバーアクション — ツールバー内に配置し、アイコンのみのシンプルなアクションボタンとして使用します。
ヒントとベストプラクティス
- コードビハインドの Click イベントより Command を優先 — MVVM パターンでは Click イベントをコードビハインドで処理するよりも、ICommand バインドを使うとテストしやすく疎結合な設計になります。
- CanExecute を活用する — 入力検証や処理中フラグを CanExecute に反映させると、ボタンの有効/無効が自動で更新され、余分なロジックが不要になります。
- コンテンツには文字列以外も可能 — テキストだけでなく、Image や StackPanel を Content として設定すると、アイコン付きボタンやリッチレイアウトのボタンを簡単に作れます。Button は ContentControl を継承しているため、任意の WPF 要素を配置できます。
- ToolTip を設定する — アイコンのみのボタンには必ず ToolTip を設定し、ユーザーがホバーで機能を確認できるようにしましょう。
- アクセシビリティ対応 — Content が画像のみのボタンには
AutomationProperties.Nameを必ず設定してください。スクリーンリーダーは Content の文字列を読み上げますが、画像だけでは読み上げられないため、視覚障害のあるユーザーがボタンの目的を理解できなくなります。 - Command vs Click イベントの使い分け — Command はバインディング経由で ViewModel にロジックを集約できますが、CanExecute の再評価タイミングに依存します。CanExecute が即座に更新されない場合(カスタム ICommand 実装で RaiseCanExecuteChanged を呼び忘れるケースなど)、ボタンが期待どおりに有効/無効化されません。コマンドが不要な単純な UI 操作(アニメーション開始など)にはコードビハインドの Click イベントを使う方がシンプルな場合もあります。
- IsDefault/IsCancel はダイアログ専用 — これらのプロパティは Window のキーボードスコープに依存するため、Page や UserControl 内では機能しません。ダイアログ以外の画面でキーボードショートカットを実装する場合は
KeyBindingを使用してください。
関連コントロール
- ToggleButton — クリックするたびに押下状態を保持するトグルボタン。CheckBox と RadioButton の基底クラス。
- RepeatButton — 押し続けている間、Click イベントを連続発火するボタン。
- Menu — コマンドを階層メニュー形式で提供する代替手段。
ソースコード
このデモ画面のソースコードは GitHub で公開しています。アプリ内の「コード表示」ボタンから各プロパティの実際の XAML を確認できます。