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

RepeatButton Inputs

RepeatButton は、押している間クリックを繰り返すボタンです。WPF 自身も、ScrollBar の矢印とトラック、Slider のトラックに使っています。

クリックが繰り返される時点

RepeatButton は ButtonBase を継承しています。ClickMode の既定値は Press で、マウスボタンを押した時点で最初のクリックになります。Delay="300"・Interval="100" で約 1 秒押し続けると、最初のクリックはすぐに、2 回目はおよそ Delay 後に、それ以降はおよそ Interval ごと(計測したマシンでは 110 ms)に来ました。Interval は正確ではありません。離したときに追加のクリックはありませんでした。バインドした Command は、クリックのたびに 1 回実行されました。範囲の制限はコマンドの中で行わないと、スピナーは範囲を越えてしまいます。

ポインターがボタンの外へ出ると繰り返しは止まります。マウスボタンを押したまま外にいる間はクリックがなく、IsPressed は False でした。ポインターが戻るとクリックが再開しました。Space を押し続けても繰り返します。Windows のキーリピートなしで、キーを押したイベント 1 回だけでも、1 秒で 8 回クリックになりました。UI オートメーションの Invoke では 1 回のクリックでした。

条件 計測値
Delay / Interval の既定値(このマシンの KeyboardDelay / KeyboardSpeed) 500 / 33 (1 / 31)
ClickMode の既定値 Press
Delay=300、Interval=100、マウスを約 1 秒押し続ける: 押している間のクリック数 / 離した後 8 / 0
押してから 1 回目のクリックまで / 1 回目から 2 回目まで 23 ms / 320 ms
その後の間隔: 最小 / 中央値 / 最大 108 ms / 110 ms / 111 ms
Command の実行回数 / Click イベントの回数 8 / 8
押したまま 0.5 秒外に出て、0.5 秒戻る: 外にいる間のクリック数(IsPressed) / 戻った後 0 (False) / 4
Space を 1 秒押し続ける、キーダウンは 1 回(OS のキーリピートなし): 押している間のクリック数 / 離した後 8 / 0
UI オートメーションの Invoke: クリック数 1

既定値と、マウスボタンや Space を押し続けたときのクリック。.NET 10 / Windows 11 で計測。

Delay と Interval は利用者のキーボードの設定で決まる

Delay と Interval の既定値は、決まった数ではありません。Windows のキーボードの「表示までの待ち時間」の設定が 1 のマシンでは Delay は 500、「表示の間隔」の設定が 31 のマシンでは Interval は 33 でした。速さが重要なら、どちらも明示します。

コードから負の Delay を設定すると ArgumentException になり、0 は受け付けられました。Interval は 0 より大きい値が必要で、コードから 0 を設定すると ArgumentException になりました。

バインドした値が不正だと既定値に戻る

デモアプリは Delay と Interval をテキストボックスにバインドしています。使えない値を入れても、直前の値は保たれません。"200" の後に "-1"、空文字、"abc" を入れると、いずれも Delay は既定値の 500 になりました。"50" の後で "0" を入れると、Interval は既定値の 33 になりました。値はボタンに渡す前に検証します。

条件 計測値
コードから Delay = -1 / Delay = 0 ArgumentException / 例外なし
コードから Interval = 0 / Interval = 1 ArgumentException / 例外なし
デモのバインド、TextBox.Text から Delay へ(入力した順) "200" -> 200, "-1" -> 500, "" -> 500, "abc" -> 500
デモのバインド、TextBox.Text から Interval へ(入力した順) "50" -> 50, "0" -> 33
縦の ScrollBar のテンプレートの中の RepeatButton(そのコマンド) LineUp, PageUp, PageDown, LineDown
横の ScrollBar のテンプレートの中の RepeatButton(そのコマンド) LineLeft, PageLeft, PageRight, LineRight
Slider のテンプレートの中の RepeatButton(そのコマンド) DecreaseLarge, IncreaseLarge

不正な値と、WPF 自身のテンプレートの中の RepeatButton。.NET 10 / Windows 11 で計測。

WPF 自身が RepeatButton を使っている場所

縦方向の ScrollBar には LineUp・PageUp・PageDown・LineDown のコマンドを持つ RepeatButton が 4 つあり(横方向では LineLeft・PageLeft・PageRight・LineRight)、両端の矢印とつまみの両側のトラックに当たります。Slider にはつまみの両側の DecreaseLarge と IncreaseLarge の 2 つがあり、矢印のボタンはありません。

デモアプリで試す

デモアプリの RepeatButton のページ。左にコントロールの一覧、右に最初の節の Delay / Interval

デモアプリの RepeatButton のページは、Delay と Interval を 2 つのテキストボックスにバインドし、最後にクリックした時刻を表示しています。欄の下の「Show Code」リンクで、その XAML を表示できます。次の XAML は、その欄(RepeatButtonUsageControl.xaml)から、スタイル、周囲の GroupBox、テキストボックスの入力制限のビヘイビアを省き、名前空間の宣言を加えたものです。

<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextBox x:Name="DelayTextBox" Text="100" />
  <TextBox x:Name="IntervalTextBox" Text="100" />

  <RepeatButton x:Name="RepeatButtonResult"
                Command="{Binding ClickCommand}"
                Content="Hold down"
                Delay="{Binding Text, ElementName=DelayTextBox}"
                Interval="{Binding Text, ElementName=IntervalTextBox}" />

  <TextBlock x:Name="ClickDateTimeTextBlock" Text="{Binding ClickDateTimeText}" />
</StackPanel>

関連するコントロールと記事

ソースコードと計測の方法

このページの挙動の記述は、すべて .NET 10 / Windows 11 で実際に動かして確かめたものです。計測には、このサイトのスクリーンショット生成ツールの RepeatButtonDemoScene を使いました。押し続ける操作は、計測用のウィンドウの上で実際のマウスを使って行いました。キーは、キーボードから打ったときと同じく WPF の入力管理(InputManager)を通して送りました。時間と既定値は、計測したマシンでの値です。

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