19

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 イベントをデータ グリッドに伝達する必要があるため、カスタム コントロールを使用してイベントを明示的に未処理としてマークしています。

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

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

ありがとう。

4

4 に答える 4

24

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

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

KeyDown ハンドラーは、スペースバーの KeyDown イベントを受け取ることはありません。

于 2013-07-13T09:05:38.160 に答える
14

問題は、スペース (およびバックスペースなど) のキーダウン イベントが、派生したコントロールに到達する前に、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.

于 2009-09-23T00:45:43.883 に答える
3

TextBoxからRestrictKeysTextBoxと言います。

public class RestrictKeysTextBox : TextBox
{
    ....
}

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

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

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

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

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

于 2011-06-14T20:36:31.160 に答える
2

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

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

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

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

よろしく、ウィム

于 2009-09-22T13:51:08.007 に答える