web-dev-qa-db-ja.com

WPF:WPF TextBoxから派生したコントロールのスペースキーに対してOnKeyDown()が呼び出されない

WPFアプリケーションには、次のようにTextBoxから派生したコントロールがあります。

public class SelectableTextBlock : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        e.Handled = false;
    }
}

OnKeyDownメソッドは、TextBoxにスペースを入力するとき、またはBackspaceを押すときに呼び出されませんが、通常の印刷可能な文字(例:「a」)や修飾キー(例)を含む他の入力に対して起動します。

IsReadOnlyをtrueに設定してこのコントロールを使用しているので、選択可能で編集不可能なテキストを表示できます。 WPFToolkitのDataGrid内で使用されるコントロールであり、SelectableTextBlockにフォーカスがある場合でも、KeyDownイベントをデータグリッドに伝播させたいので、カスタムコントロールを使用してイベントを未処理として明示的にマークしています。

問題は、イベントが特定のキーの制御にさえ到達していないことです。データグリッドでOnPreviewKeyDownを使用してこれを回避することはできません。これは、データグリッドで使用される他のコントロールがスペースKeyDownイベントを飲み込むためです。

スペースキーのKeyDownイベントを取得して伝播する方法を知っている人はいますか?

ありがとう。

17
Ergwun

問題は、スペース(およびバックスペースなど)のキーダウンイベントが、派生したコントロールにバブルアップする前に、TextBox内ですでに処理されていることです。 Wimが投稿したように、私はテキスト作成プロセスの一部として想定しています。

これを回避するために、すでに処理されている場合でもキーダウンイベントを受信するハンドラーを追加し、Handledメンバーをfalseに設定して、正常にバブリングを続行できるようにしました。以下の例では、スペースキーに対してこれを実行しますが、私の場合は、SelectedableTextBlockで処理したくないキーイベントに対してこれを実行する必要があります本当に親がどのような重要なイベントに興味を持っているのかまだわかりません。

public class SelectableTextBlock : TextBox
{
    public SelectableTextBlock() : base()
    {
        this.AddHandler(SelectableTextBlock.KeyDownEvent, new RoutedEventHandler(HandleHandledKeyDown), true);
    }

    public void HandleHandledKeyDown(object sender, RoutedEventArgs e)
    {
        KeyEventArgs ke = e as KeyEventArgs;
        if (ke.Key == Key.Space)
        {
            ke.Handled = false;
        }
    }
    ...
}

もちろん、誰かがより良い解決策を持っているかどうか私はまだ興味があります...

ありがとう、E。

14
Ergwun

PreviewKeyDownイベントは、まさにこの種のもののために存在します。

private void spacebarHandler_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Space)
        e.Handled = true;
}

KeyDownハンドラーは、スペースバーのKeyDownイベントを受信しません。

19
ivan

この問題は、テキストボックス内のスペースとイベントで一度発生しました。スペース文字を追加または削除した場合にのみ、イベントがトリガーされませんか?

これは私が答えとして得たものです:( http://social.msdn.Microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b

一部のIMEは空白のキーストロークをテキスト構成プロセスの一部として扱うため、TextInputイベントを介して正しい合成テキストを報告するためにAvalonが消費するのはそのためです。

私は完全に範囲外である可能性がありますが、このスレッドをすぐに読んで、私がかつて持っていたその問題について考えさせられました。

よろしく、ウィム

2
hypo

TextBoxからRestrictKeysTextBoxという発言を導き出します。

public class RestrictKeysTextBox : TextBox
{
    ....
}

RestrictKeysTextBoxのOnPreviewKeyDownイベントをオーバーライドします。

このオーバーライドに次のようにロジックを配置します。

if (e.Key == Key.Space)
{
    e.Handled = true;
}

RestrictKeysTextBoxのインスタンスをDataGridにバインドします。

これは、DataGridのOnPreviewKeyDownをオーバーライドせずに機能し、関連する問題を排除する必要があります。

2
Mac