1

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

控件使用该KeyDown事件并将SuppressKeyPress标志设置为 true,但这发生上述表单键预览之后,因此没有效果。

有某种 KeyPostview 吗?

当控件有相关的按键使用时,我如何不关闭表单?

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

4

4 回答 4

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;
    }
于 2010-12-29T21:09:40.143 回答
1

您正在与 Escape 键竞争 Big Time。与 Enter 键一起,它是标准 Windows 用户界面中非常重要的键。只需在表单上放置一个按钮并将表单的 CancelButton 属性设置为其他按钮,这会将击键吸引到该按钮。

为了与之竞争,你必须创建一个控件,告诉 Winforms 你真的认为 Escape 键重要。这需要覆盖 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

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

于 2010-12-29T21:02:41.673 回答
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 回答