【发布时间】:2018-05-03 22:07:34
【问题描述】:
我正在开发一个 C# 项目。问题是,当背景窗口不是活动窗口时,像 mouse-enter 这样的背景事件会使背景窗口突出显示为焦点。解决方案的策略是在设置此重点之前添加预防措施。
我的尝试包括以下策略:
在调用control.Focus() 之前,我想实现一个涉及GetActiveWindow() function 的条件,以匹配控件的顶级父级关联窗口句柄。对于后者,我使用Control.TopLevelControl()。但是,每次我这样做时,我都会为这个属性获得null。根据MSDN reference 的原因是该控件不是窗体上的父级。
尝试了 sn-p:
if (myControl.TopLevelControl.Handle == GetActiveWindow())
{
this.myControl.Focus();
}
代码背景:此代码不归我所有。所以,请原谅我太抽象了。我会尽量详细说明。相关控件是一个私有成员自定义布局面板,它继承自 System.Windows.Forms.Panel,其中 DoubleBuffered 属性设置为 true。此控件已添加到继承自 UserControl(Windows 窗体)的内部部分类中。后一个控件已通过公共部分类(也继承自用户控件)上的私有成员 SplitContainer(Windows 窗体)添加。
在这个布局面板的用户控件的构造函数中,偶数被添加为:
myLayoutPanel.MouseEnter += this.myLayoutPanel_MouseEnter;
没有我改变的事件看起来像:
private void myLayoutPanel_MouseEnter(object sender, EventArgs e)
{
myLayoutPanel.SuspendLayout();
myLayoutPanel.Focus();
myLayoutPanel.ResumeLayout(false);
}
此外,我手动查看了控件父层次结构的句柄,但始终无法匹配到活动窗口句柄。直观地说,我觉得GetActiveWindow() 使用互操作性深入研究非托管代码以获取句柄,而顶级属性保留在托管区域中,因此有其局限性。不过我可能错了。
有人对此有什么想法吗?
【问题讨论】:
-
events like mouse-enter make a background window pop out in focus when it is not the active window这实际上不是正常行为。您是否在 MouseEnter 事件中运行了可以使表单成为焦点的代码? -
当您不告诉我们为什么您的用户控件未嵌入表单中时,您并没有完全帮助我们。猜测:当 myControl.IsHandleCreated 为 false 时不要做任何事情。
-
你确定你的窗口(窗体)是真的活跃吗?窗口/表单可以在顶部(即使不是最顶部)并且处于非活动状态。
-
在winforms(和Win32 UI)中是动态添加的。这不是问题。问题是,您的表单没有焦点。问题将在其他地方。我认为这将是“鼠标输入”区域中的内容。尝试详细说明这部分,我们可能会有所帮助。
-
正如我所说 - 控件的组成并不重要。创建最小的代码示例,它(不)工作。我的提示(不知道完整代码)是处理鼠标事件和弹出表单的部分。不是表单中控件的组成。