Windows Forms: Unable to Click to Focus a MaskedTe

2019-01-15 16:44发布

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()

3条回答
Luminary・发光体
2楼-- · 2019-01-15 17:11

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:

    private void MaskedTextBoxSetFocus(object sender, EventArgs e)
    {
        var mtb = (MaskedTextBox)sender;
        mtb.Focus();
    }

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.

查看更多
够拽才男人
3楼-- · 2019-01-15 17:19

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.

查看更多
不美不萌又怎样
4楼-- · 2019-01-15 17:30

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:

    newReportForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None

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:

    newReportForm.ControlBox = False
    newReportForm.Text = ""

Either fix solves the mouse click problem.

查看更多
登录 后发表回答