在没有激活的情况下与表单交互

时间:2009-09-27 18:59:04

标签: c# .net winforms focus activation

我正在尝试在我的项目中实现代码完成弹出窗口。窗口来自Form。它包含两个控件:从UserControl派生的自定义列表(它显示带图标的完成可能性)和VScrollBar。

当弹出窗口出现时,它不会从编辑器中窃取焦点(窗体的ShowWithoutActivation被覆盖以返回true),编辑器会向弹出窗口发送某些击键,以便用户可以使用键盘与其进行交互。到目前为止它的工作就像一个魅力。

问题是,我想让用户也使用鼠标。但是,当用户点击弹出窗口时,其表单会激活并从编辑器中窃取焦点。我可以通过将焦点重新放回编辑器来做出反应,我甚至设置了一个定期执行此操作的计时器,但除了是一个糟糕的解决方案之外,编辑器的标题栏总是在发生这种情况时闪烁(当弹出窗口是点击)。

是否有任何方法可以与弹出窗体(使用鼠标)进行交互,而不会激活窗体?

ShowWithoutActivation的文档中写道:“如果您的非激活窗口需要使用UI控件,您应该考虑使用ToolStrip控件,例如ToolStripDropDown。这些控件是无窗口的,并且在选择窗口时不会激活窗口“。这看起来就像我需要的东西,但我想使用自定义控件和滚动条。

同样的问题是工具提示显示这两个箭头切换方法重载(从VS中已知) - 整个表单根本不使用任何控件(只渲染文本和箭头),但点击时,它不应激活。问题可归纳为“如何创建永远不会激活的表单,但允许用户与内部的certail控件进行交互?”。

感谢。

3 个答案:

答案 0 :(得分:0)

只需覆盖onFocus事件......

public partial class myListBox:ListBox
{
    protected override void OnGotFocus(EventArgs e)
    {
    }
}

答案 1 :(得分:0)

问题是你正在使用一个Form而不是构建一些自定义控件,它不像Form那样在自己的UI线程中运行。 只要表单激活/聚焦,窗口就会处理闪烁和突出显示。我能想到的唯一一件事就是让你的Form无边框并创建/绘制/处理你自己的标题栏,这些标题栏在聚焦时不会闪烁。

答案 2 :(得分:0)

好的,我可能找到了解决方案。密钥似乎是WM_MOUSEACTIVATE消息,弹出窗体必须拦截并以MA_NOACTIVATE响应。但是有一个问题 - 来自UserControl的控件在点击时仍然会抓住焦点(滚动条幸运地不再存在)。问题似乎出现在UserControl.OnMouseDown方法中,该方法在内部将焦点放在控件上。有一些方法可以解决这个问题:

  • 从Control而不是UserControl
  • 派生控件
  • 覆盖OnMouseDown方法,而不是在那里调用base.OnMouseDown
  • 使控件的CanFocus属性返回false,但这似乎不可能,因为这意味着使控件不可见或未启用,这是不合需要的

弹出窗体窃取焦点的最后一种情况似乎是它的大小调整(使用鼠标)结束。但是在这里调用Owner.Activate()作为Activated事件的结果是安全的......