1

KeyPreviewProcessKeyEventArgs、またはその他のおかげで、ESCキーが押されるとフォームが閉じますProcessCmdKey。しかし、ESCが押されたときに非常に関連性のあることを行うフォームにコントロールがあり(それ自体が非表示になります)、それが発生したときにフォームを閉じてはなりません。

コントロールはKeyDownイベントを使用してSuppressKeyPressフラグを true に設定しますが、これは前述のフォーム キー プレビューの後に発生するため、効果がありません。

ある種の KeyPostview はありますか?

コントロールにキー ヒットの関連する使用法がある場合、フォームを閉じないようにするにはどうすればよいですか?

編集: ESC を処理するコントロールは、手作りの ListView に埋め込まれたテキスト ボックスです。ユーザーがセルをクリックするとテキストボックスが表示され、編集が有効になります。新しいテキストを検証するには、ENTER が便利です (これは、他の何かにフォーカスを与えるため、既に機能しています)。編集をキャンセルするには、ESC が最も自然なようです。

4

4 に答える 4

1

OK-これは機能します:

class CustomTB : TextBox
{
    public CustomTB()
        : base()
    {
        CustomTB.SuppressEscape = false;
    }

    public static bool SuppressEscape { get; set; }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        CustomTB.SuppressEscape = (e.KeyCode == Keys.Escape);
        base.OnKeyUp(e);
    }
}

あなたのフォームで:

    public Form1()
    {
        InitializeComponent();
        this.KeyPreview = true;
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Escape && !CustomTB.SuppressEscape)
        {
            this.Close();
        }
        CustomTB.SuppressEscape = false;
    }
于 2010-12-29T21:09:40.143 に答える
1

あなたは Escape キーをめぐって大競争を繰り広げています。Enter キーと並んで、Windows の標準ユーザー インターフェイスでは非常に重要なキーです。フォームにボタンをドロップし、フォームの CancelButton プロパティを他のボタンに設定するだけで、そのボタンにキーストロークが吸い込まれます。

それに対抗するには、Escape キーがより重要であると本当に考えていることを Winforms に伝えるコントロールを作成する必要があります。IsInputKey プロパティをオーバーライドする必要があります。このような:

using System;
using System.Windows.Forms;

class MyTexBox : TextBox {
    protected override bool IsInputKey(Keys keyData) {
        if (keyData == Keys.Escape) return true;
        return base.IsInputKey(keyData);
    }
    protected override void OnKeyDown(KeyEventArgs e) {
        if (e.KeyData == Keys.Escape) {
            this.Text = "";   // for example
            e.SuppressKeyPress = true;
            return;
        }
        base.OnKeyDown(e);
    }
}
于 2010-12-30T00:30:42.383 に答える
0

基本的な問題は、Closeが呼び出されたときにフォームのDisposeメソッドが呼び出されるため、フォームが閉じられ、それについてできることはあまりないということです。

これを回避するには、UserControlにマーカーインターフェイス(ISuppressEscなど)を実装させます。フォームのKeyUpハンドラーは、現在フォーカスされているコントロールを見つけて、フォーカスされているコントロールがISuppressEscを実装している場合は、クローズをキャンセルできます。ネストされたコントロールである可能性がある場合は、フォーカスされたコントロールを見つけるために追加の作業を行う必要があることに注意してください。

public interface ISuppressEsc
{
    // marker interface, no declarations
}

public partial class UserControl1 : UserControl, ISuppressEsc
{
    public UserControl1()
    {
        InitializeComponent();
    }

    private void textBox1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Escape)
        {
            textBox1.Text = DateTime.Now.ToLongTimeString();
        }
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        KeyPreview = true;
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        var activeCtl = ActiveControl;
        if (!(activeCtl is ISuppressEsc) && e.KeyCode == Keys.Escape)
        {
            Close();
        }
    }
}
于 2010-12-29T21:50:15.120 に答える
0

どのコントロールが最初にフォーカスされているかを確認できますか? フォーム上にエスケープ キーに関連する操作を行うコントロールが 1 つしかない場合は、フォームを閉じる前に、そのコントロールにフォーカスがあるかどうかを確認してください。

于 2010-12-29T21:02:41.673 に答える