0

我有一个带有 ToolStripDropDownButton 的自定义控件。ToolStripDropDownButton 有许多工具条项目(特别是一个自定义工具条项目,它们是复选框)。用户可以选择他们想要的复选框项目,我处理 DropDownClosed 事件,然后使用这些选中的项目。

目的是让用户通过点击退出键来取消他的选择。问题是按下 Escape 键时也会触发 DropDownClosed 事件。因此,当用户选择选项并想要按 Escape 取消选择时,DropDownClosed 事件会触发,我最终会“应用”这些设置。

我尝试在托管 ToolStripDropDownButton 的控件上使用以下覆盖:

protected override bool ProcessCmdKey
protected override bool ProcessKeyPreview
protected override void WndProc

没有太大的成功,因为在处理任何这些事件之前下拉菜单似乎隐藏了。修改此行为的最佳方法是什么?

4

3 回答 3

2

尝试使用这个版本的ToolStripDropDown它拦截Esc关闭下拉菜单的密钥:

public class ToolStripDropDownEx : ToolStripDropDown {

  protected override bool ProcessDialogKey(Keys keyData) {
    if (keyData == Keys.Escape)
      return true;
    else
      return base.ProcessDialogKey(keyData);
  }
}
于 2011-12-20T15:28:03.067 回答
0

KeyDown 或 KeyPressed 事件呢?至少其中一个应该希望在 DropDownClosed 事件之前触发,然后您可以检查是否按下了 Escape,以便您可以为 DropDownClosed 处理程序设置一个标志。

编辑: 如果在 DropDownClosed 事件之后触发 ProcessCmdKey 或 ProcessKeyPreview,您可以使用计时器构建延迟。DropDownClosed 启动计时器,然后 ProcessCmdKey 或 ProcessKeyPreview 可以设置一个标志,如果 Escape 被按下。当计时器滴答时,您可以撤消或应用用户所做的检查。

于 2011-12-20T07:56:41.807 回答
0

好的,覆盖在 ToolStripDropDownButton 上不起作用的原因是它不是具有焦点的组件。显示下拉菜单时,下拉菜单上的项目具有焦点,并且在显示下拉菜单时会触发 toolBoxButton 项目上的所有可用覆盖(ProcessCmdKey、ProcessDialogKey 等)。

最后,我为 ToolStrip 项本身(在本例中为复选框)和适应 ToolStripDropDownButton 创建了两个派生类。

public class EscapingToolStripCheckBox : CustomControls.ToolStripCheckBox
{
    private EscapingToolStripDropDownButton _parent;

    public EscapingToolStripCheckBox(EscapingToolStripDropDownButton parent)
        : base()
    {
        _parent = parent;
    }

    protected override bool ProcessCmdKey(ref Message m, Keys keyData)
    {
        if (keyData == Keys.Enter)
        {
            _parent.HandleSelection(false);
            return true;
        }
        else if (keyData == Keys.Escape)
        {
            _parent.HandleSelection(true);
            return true;
        }
        // Dont need to execute HandleSelection under any other condition. 

        return base.ProcessCmdKey(ref m, keyData);
    }

}

...其中 HandleSelection 采用布尔值来确定是否取消选择。

    public void HandleSelection(bool selectionCancelled)
    {
        _selectionCancelled = selectionCancelled;
        this.HideDropDown();
    }

从那里,我可以轻松地检查属性(无论是在控件本身上还是作为事件参数的一部分),以确定 DropDownClosed 事件是否被视为已取消。

于 2011-12-28T12:20:57.077 回答