如何在ESC键被击中时关闭表单,但仅当没有Control处理它时?

时间:2010-12-29 21:00:00

标签: c# winforms hotkeys keydown keypreview

由于KeyPreviewProcessKeyEventArgsProcessCmdKey或其他原因,我按下ESC键时会自动关闭一个表单。但是我在该表单上有一个控件,当按下ESC时它会执行非常相关的操作(它隐藏自己),并且当发生这种情况时不应该关闭表单。

控件使用KeyDown事件并将SuppressKeyPress标志设置为true,但在上述表单键预览后发生,因此无效。

是否有某种KeyPostview?

如果控件具有相关的按键命中功能,如何关闭表单?

编辑:控制处理ESC是嵌入在hand-maid ListView中的文本框。当用户单击单元格并启用编辑时,将显示文本框。为了验证新文本,ENTER会很好(已经有效,因为将焦点放在其他任何东西上)。要取消版本,ESC似乎最自然。

4 个答案:

答案 0 :(得分:1)

好的 - 这有效:

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;
    }

答案 1 :(得分:1)

你正在通过Escape键竞争Big Time。与Enter键一起,这是标准Windows用户界面中非常重要的键。只需在窗体上放一个按钮,然后将窗体的CancelButton属性设置为其他按钮,这将触发该按钮的按键。

要与之竞争,您必须创建一个控件,告诉Winforms您确实认为Escape键 more 很重要。这需要重写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);
    }
}

答案 2 :(得分:0)

您可以查看首先关注哪个控件?如果表单上只有一个控件执行与转义键相关的操作,请在关闭表单之前检查该控件是否具有焦点。

答案 3 :(得分:0)

基本问题是调用Close时调用窗体的Dispose方法,因此窗体将关闭,你可以做的事情并不多。

我会通过让UserControl实现标记接口来解决这个问题,比如ISuppressEsc。然后,窗体的KeyUp处理程序可以找到当前聚焦的控件,并在聚焦控件实现ISuppressEsc时取消关闭。请注意,如果它可能是嵌套控件,则必须对find the focused control执行额外的工作。

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();
        }
    }
}