2

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

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

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

有没有办法与不会激活表单的弹出表单(使用鼠标)进行交互?

ShowWithoutActivation 的文档中写道:“如果你的非激活窗口需要使用 UI 控件,你应该考虑使用 ToolStrip 控件,例如 ToolStripDropDown。这些控件是无窗口的,当它们被选中时不会导致窗口激活。” 这似乎正是我需要的东西,但我想使用自定义控件和滚动条。

同样的问题是显示这两个箭头以切换方法重载的工具提示(从 VS 已知) - 整个表单根本不使用任何控件(仅呈现文本和箭头),但是当单击时,它不应该激活. 问题可以总结为“如何创建一个永远不会激活的表单,但允许用户与里面的某些控件进行交互?”。

谢谢。

4

3 回答 3

0

只需覆盖 onFocus 事件...

public partial class myListBox:ListBox
{
    protected override void OnGotFocus(EventArgs e)
    {
    }
}
于 2009-09-28T02:33:15.973 回答
0

The issue is that you're using a Form for this rather than building some custom control that doesn't run in its' own UI thread like a Form does. The flashing and highlighting is handled by windows whenever a Form activates/focuses. The only thing I cay think of is to make your Form borderless and create/draw/handle your own title bar that doesn't flash when focused.

于 2009-09-30T05:04:59.323 回答
0

OK, I may have found a solution. The key seems to be WM_MOUSEACTIVATE message, which the popup form must intercept and respond with MA_NOACTIVATE. But there's a catch - the control derived from UserControl still grabs focus when clicked (the scrollbar luckily doesn't anymore). The problem seems to be in the UserControl.OnMouseDown method, which internally puts focus on the control. There are some ways to fix this:

  • derive the control from Control instead of UserControl
  • override the OnMouseDown method and not call base.OnMouseDown there
  • make the control's CanFocus property return false, but this seems not possible, because that means to make the control either not visible or not enabled, which is both undesirable

The last case when the popup form steals focus seems to be when its resizing (using mouse) ends. But it is safe here to call Owner.Activate() as a result to Activated event...

于 2009-10-05T10:18:24.283 回答