Windows 窗体:无法在非顶级窗体中单击以聚焦 MaskedTextBox
正如标题所示,我显示了一个子窗体,其 TopLevel 属性设置为 False,并且我无法单击它包含的 MaskedTextBox 控件(以便将焦点集中到它)。不过,我可以通过使用键盘上的 TAB 来将焦点集中到它上。
子窗体包含其他常规文本框控件,我可以毫无问题地单击这些控件来聚焦,尽管它们也表现出一些奇怪的行为:例如,如果我在文本框中有一个值,并且我尝试从末尾拖动单击字符串到开头,什么也没有发生。事实上,我根本无法使用鼠标将光标移动到文本框的文本内(尽管键盘箭头键可以工作)。
我不太担心奇怪的 TextBox 行为,但为什么我不能通过单击来激活我的 MaskedTextBox?
下面是显示表单的代码:
Dim newReportForm As New Form
Dim formName As String
Dim FullTypeName As String
Dim FormInstanceType As Type
formName = TreeView1.SelectedNode.Name
FullTypeName = Application.ProductName & "." & formName
FormInstanceType = Type.GetType(FullTypeName, True, True)
newReportForm = CType(Activator.CreateInstance(FormInstanceType), Form)
Try
newReportForm.Top = CType(SplitContainer1.Panel2.Controls(0), Form).Top + 25
newReportForm.Left = CType(SplitContainer1.Panel2.Controls(0), Form).Left + 25
Catch
End Try
newReportForm.TopLevel = False
newReportForm.Parent = SplitContainer1.Panel2
newReportForm.BringToFront()
newReportForm.Show()
Like the title says, I've got a Child form being shown with it's TopLevel property set to False and I am unable to click a MaskedTextBox control that it contains (in order to bring focus to it). I can bring focus to it by using TAB on the keyboard though.
The child form contains other regular TextBox controls and these I can click to focus with no problems, although they also exhibit some odd behavior: for example if I've got a value in the Textbox and I try to drag-click from the end of the string to the beginning, nothing happens. In fact I can't use my mouse to move the cursor inside the TextBox's text at all (although they keyboard arrow keys work).
I'm not too worried about the odd TextBox behavior, but why can't I activate my MaskedTextBox by clicking on it?
Below is the code that shows the form:
Dim newReportForm As New Form
Dim formName As String
Dim FullTypeName As String
Dim FormInstanceType As Type
formName = TreeView1.SelectedNode.Name
FullTypeName = Application.ProductName & "." & formName
FormInstanceType = Type.GetType(FullTypeName, True, True)
newReportForm = CType(Activator.CreateInstance(FormInstanceType), Form)
Try
newReportForm.Top = CType(SplitContainer1.Panel2.Controls(0), Form).Top + 25
newReportForm.Left = CType(SplitContainer1.Panel2.Controls(0), Form).Left + 25
Catch
End Try
newReportForm.TopLevel = False
newReportForm.Parent = SplitContainer1.Panel2
newReportForm.BringToFront()
newReportForm.Show()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我尝试了你的代码,这次得到了很好的重现。正如我在原来的帖子中提到的,这确实是一个窗口激活问题。您可以在 Spy++ 中看到这一点,注意 WM_MOUSEACTIVATE 消息。
发生这种情况是因为您显示带有标题栏的表单。这使 Windows 窗口管理器相信该窗口可以被激活。这实际上不起作用,它不再是顶级窗口。从标题栏可以看出,它永远不会用“窗口激活”颜色绘制。
您必须从表单中删除标题栏。最好通过将这一行添加到您的代码中来完成:
这会将表单转换为一个与 UserControl 无法区分的控件。您仍然可以通过使用以下代码来使其与众不同:
任一修复都可以解决鼠标单击问题。
I tried your code and got a good repro this time. As I mentioned in my original post, this is indeed a window activation problem. You can see this in Spy++, note the WM_MOUSEACTIVATE messages.
This happens because you display the form with a caption bar. That convinces the Windows window manager that the window can be activated. That doesn't actually work, it is no longer a top-level window. Visible from the caption bar, it never gets drawn with the "window activated" colors.
You will have to remove the caption bar from the form. That's best done by adding this line to your code:
Which will turn the form into a control that's otherwise indistinguishable from a UserControl. You can still make it distinctive by using this code instead:
Either fix solves the mouse click problem.
这是一个悲惨的错误,我花了很长时间才找到这个问题。我们正在做与OP完全相同的事情,在拆分容器内显示一个表单。我的解决方法是向 MaskedTextBox 的 Click 事件添加一个事件处理程序:
这适用于 MaskedTextBox,但我担心由于此错误而导致的其他奇怪行为,因此我可能会按照接受的答案设置边框样式。
This is a miserable bug and it took me a long time to find this question. We're doing exactly the same thing as the OP, displaying a Form inside a split container. My workaround was to add an event handler to the MaskedTextBox's Click event:
This works for the MaskedTextBox but I'm concerned about other odd behavior due to this bug so I will probably set the border style as in the accepted answer.
文本框行为是同一问题的症状。有东西正在吞噬鼠标按下通知。您的代码片段没有解释它。表单确实会吞掉激活它们的鼠标单击,但这是一次性行为,可以通过将其 TopLevel 属性设置为 False 来关闭。
所剩无几了。其中一个候选者是 Control.Capture 属性,该属性在按钮的 MouseDown 事件中打开,以便无论鼠标移动到何处,该按钮都可以看到 MouseUp 事件。这也是一次性的效果。注意在 MouseDown 事件中设置焦点的控件。
另一个是表单中的某种 IMessageFilter 代码,它正在处理 WM_LBUTTONDOWN 消息。
The text box behavior is a symptom of the same problem. Something is swallowing mouse down notifications. It isn't explained by your code snippet. Forms indeed swallow the mouse click that activates them, but that is a one-time behavior and is turned off by setting its TopLevel property to False.
Not much left. One candidate is the Control.Capture property, turned on at the MouseDown event for a button so that the button can see the MouseUp event, no matter where the mouse moved. That's a one-time effect as well. Watch out for controls that set the Focus in a MouseDown event.
The other is some kind of IMessageFilter code in your form(s) that's eating WM_LBUTTONDOWN messages.