CheckBox、TextBlock、および TextBox を含むカスタム データ テンプレートを含む ListBox があります。通常、ListBox 内の項目を選択すると、実際には基になる ListBoxItem にフォーカスがあるため、上下のキーに反応します。さらに、CheckBox にフォーカスがある場合、上下のキー自体には何もしないため、喜んでそれらを無視し、基礎となる ListBoxItem によっても処理されます。ここまでは順調です。
ただし、TextBox には上下のキーに対する独自の処理規則があり、キャレットをテキスト内の 1 行上または下に名前を付けて移動します。そのため、TextBox にフォーカスがある場合、上下のキーは ListBox の選択のナビゲーションを壊し、編集にも役立ちません。
ここで、PreviewKeyDownEvent を処理し (以下で行いますが、理由は異なります)、押されたキーに応じて動作を手動で処理できますが、これは非常に具体的な解決策であり、コントロールがコンテナーの動作を認識している必要があります。
完璧な世界 (および疑似コード) では、 MyTextBox.KeysToIgnore(Up, Down) または同様のことを言って、それを実行させたいと思います...それらのキーは、存在しないかのように無視します。(繰り返しますが、飲み込むのではなく、無視して通過させます。)
しかし、それまでは、これが私が思いついたものです。これは機能しているように見えますが、私にはとても「ハック」に見えます...
private void PreviewKeyDownHandler(object sender, KeyEventArgs e) {
switch (e.Key){
case Key.Up:
case Key.Down:
case Key.OtherKeyToIgnore
case Key.AndAnother
e.Handled = true;
FrameworkElement target = VisualTreeHelper.GetParent(
e.Source as DependencyObject) as FrameworkElement;
target.RaiseEvent(
new KeyEventArgs(
e.KeyboardDevice,
PresentationSource.FromVisual(target),
0,
e.Key
){
RoutedEvent=Keyboard.KeyDownEvent
}
);
break;
}
}
これには、PreviewKeyDown イベントをターゲットに送信しないという欠点もあります。これを回避して、最初にそのイベントを送信し、実際の KeyDown メッセージを送信する前に e.Handled を確認することで偽装することができます。 .上記で処理したように、偽のイベントをいつ送信するかを知るために、本当の「キーアップ」イベントを取得することはありません。さらに、通常の非プレビュー バージョンとは逆方向にバブルするため、PreviewKeyxxx メッセージの方向性も破ることになると確信しています。(たぶん内部で処理されていると思いますが、そうではないと思います。)
私が言ったように...ハッキー、ハッキー、ハッキー!
しかし、それは機能するので、それがあります。そして、これを Attached Behaviors を介して実装できるため、このルートに行きました。(添付されたビヘイビアーの実装では、これは case ステートメントではなく、XAML で指定したキーのコレクションに対するチェックです。) 必要な他のすべてのビヘイビアーを失うという考えは好きではありません。
繰り返しますが、「Hey TextBox... 上または下のキーが押されているのを見たら、STFU ya b*stard!!」と言いたいだけです。それ以外の場合は、キーを透過的にします。
誰か考えますか?