WPF Standard Control Demo App › Button

Button Inputs

Button is the most commonly used command trigger control in WPF. It fires a Click event when pressed and supports command binding via the ICommand interface. Button inherits from ButtonBase, which provides ClickMode and Command-related properties.

Overview

The WPF Button control is the primary mechanism for triggering user actions in desktop applications. It descends from ButtonBase, which itself extends ContentControl, meaning a Button can host any arbitrary content โ€” text, images, icons, or complex panel layouts โ€” not just a simple label. This flexibility makes it easy to create richly styled action buttons that match your application's visual design.

One of Button's most important features for MVVM (Model-View-ViewModel) architectures is its built-in support for the ICommand interface through the Command property. When a command is bound, WPF automatically disables the button whenever ICommand.CanExecute returns false, and re-enables it when conditions change. This eliminates the need for manual enabled/disabled logic in code-behind and keeps UI state synchronized with application state.

The ClickMode property inherited from ButtonBase controls exactly when the Click event fires. The default Release mode fires on mouse-button release, matching standard desktop conventions. Press mode fires immediately on mouse-down, useful for rapid-fire scenarios. Hover mode fires when the pointer merely moves over the button, enabling touchless interaction patterns.

Two special boolean properties โ€” IsDefault and IsCancel โ€” simplify dialog implementation. Setting IsDefault="True" makes the button respond to the Enter key when no other element captures it, while IsCancel="True" binds the button to the Escape key. Together they let developers build keyboard-accessible dialogs with minimal code.

Screen Preview

button demo screen

Demonstrated Properties

The following properties are demonstrated interactively in the WPF Standard Control Demo App. Each property can be configured in real time within the app to observe its behavior.

Property Values Description
IsCancel bool Use this on a "Cancel" button in a dialog when you want the Escape key to dismiss the window without the user needing to click. When True, pressing Escape triggers this button's Click regardless of where focus is. Combined with Window.DialogResult = false, it implements the standard cancel pattern. Pitfall: This property only works within a Window scope โ€” it has no effect inside a UserControl or Page. Also, setting IsCancel="True" on more than one button in the same Window can cause unexpected conflicts; keep it to one per Window.
IsDefault bool Use this on the primary action button (e.g., "OK" or "Search") in a dialog or form so users can confirm with Enter without tabbing to the button. When True, pressing Enter triggers this button's Click as long as the focused element does not consume the key itself. Pitfall: Only one button per Window should have IsDefault="True". Also, when a multi-line TextBox with AcceptsReturn="True" has focus, Enter inserts a new line and the IsDefault button is never fired.
ClickMode (ButtonBase) Release / Press / Hover Controls when the Click event fires relative to the mouse interaction. Release (default) fires when the mouse button is released โ€” it also allows the user to cancel by dragging off the button before releasing. Press fires immediately on mouse-down, making it suitable for game controls or drag-start triggers where instant response is required. Hover fires as soon as the cursor enters the button bounds, which is useful for ribbon-style menus that open on hover. Pitfall: Hover mode can fire accidentally when the mouse merely passes over the button. Limit its use to intentional hover-activation patterns and always provide clear visual feedback so users know the button is activated.
IsPressed (ButtonBase) bool (ReadOnly) Use this inside a custom ControlTemplate to drive pressed-state visuals โ€” for example, a scale-down animation or background color change while the button is held. A DataTrigger in the template can watch this value to apply the effect. Pitfall: Mouse clicks reliably set IsPressed, but pressing Space on a focused button may not update it consistently. For keyboard-only visual feedback, rely on FocusVisualStyle or a separate keyboard-focused state rather than IsPressed alone.
Command (ButtonBase) ICommand Use this in MVVM applications to bind a ViewModel's ICommand to the button, eliminating click-handling code in code-behind. WPF automatically disables the button when CanExecute returns false and re-enables it when conditions change. The re-evaluation is triggered by CommandManager.RequerySuggested, which fires on UI interactions like focus changes. Pitfall: If CanExecute performs expensive work (database queries, slow computations), it will block the UI thread every time WPF re-evaluates it. Keep CanExecute fast by checking only a cached flag, and update that flag when state actually changes.
CommandParameter (ButtonBase) object Use this when multiple buttons share the same command but need to pass different context values โ€” for example, CommandParameter="{Binding SelectedItem}" to pass the currently selected item to a shared Delete command. The parameter is received by both Execute and CanExecute. When set via a normal Binding, the parameter updates automatically as the source changes. Pitfall: If you use Mode=OneTime or assign a static value directly, the parameter will not update when the underlying data changes. Always verify that the binding mode matches the dynamic or static nature of the value you intend to pass.

XAML Example

The following XAML demonstrates typical Button usage, including command binding and keyboard shortcuts:

<StackPanel Margin="16" Spacing="8">

  <!-- Basic button with Click event handler -->
  <Button Content="Click Me"
          Width="120" Height="32"
          Click="OnButtonClick" />

  <!-- MVVM command binding with a parameter -->
  <Button Content="Save"
          Command="{Binding SaveCommand}"
          CommandParameter="{Binding CurrentItem}"
          IsDefault="True" />

  <!-- Cancel button responding to Escape key -->
  <Button Content="Cancel"
          Command="{Binding CancelCommand}"
          IsCancel="True" />

  <!-- Button with icon content -->
  <Button Width="140" Height="36">
    <StackPanel Orientation="Horizontal" Spacing="6">
      <Image Source="/Icons/save.png" Width="16" Height="16" />
      <TextBlock Text="Save File" VerticalAlignment="Center" />
    </StackPanel>
  </Button>

</StackPanel>

Common Use Cases

Tips and Best Practices

Related Controls

Source Code

The source code for this demo screen is available on GitHub. Use the built-in code view buttons in the app to see the exact XAML for each property.

View Button source code on GitHub →