Windows Forms: Unable to Click to Focus a MaskedTextBox in a Non TopLevel Form - vb.net

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

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.

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.

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.

Related

How to hide and show group of controls using Panel [duplicate]

I am designing a multipage windows form using panels.
I'm displaying a login form and validating the button click, and want to hide the login panel and show the main panel.
However, when I click the button, the login panel disappears alright, but the main panel does not appear. since there is nothing to display, the form window shrinks to just the minimize/maximize/close buttons.
Here's the code for the button:
private void btn_login_Click(object sender, EventArgs e)
{
if (pwdBox.Text == optopwd)
{
MessageBox.Show("Good Morning!!");
loginpanel.Visible = false;
mainpanel.Visible = true;
}
else MessageBox.Show("Incorrect password!");
pwdBox.Text = "";
}
Please let me know what I have missed/misunderstood. Thanks!
Edit:
Screenshots:
Login Screen:
http://img641.imageshack.us/img641/9310/loginscreenj.jpg
Empty window:
http://img163.imageshack.us/img163/1376/emptyx.jpg
The standard mistake is that you accidentally put the mainpanel inside the loginpanel. So when you make loginpanel invisible, the mainpanel can never become visible. This accident is common in the designer, it won't let you put two panels on top of each other. You fix it with View + (Other Windows) + Document Outline. Drag mainpanel and drop it on the form. You'll have to fix the Location property by editing it in the Properties window instead of moving the panel with the mouse.
An entirely different approach is to use a TabControl. Easy in the designer, you just need to hide the tabs at runtime. Code is here.
Or use two UserControls.
Looks like your for is automatically resizing. There are 2 properties on the form responsible for auto size:
AutoSize = True;
AutoSizeMode = GrowAndShrink;
If you have the above settings then your form would shrink just to control panel (buttons) if there's nothing else to display.
Let me know if that helps.
UPDATED
also... does your control "pwdBox" belong to main panel?
Two suggestions:
Try setting the height attribute to 100%
mainpanel.Height = 100%
If that doesn't work, ensure that the page isn't initializing with mainpanel.visible set to false on a postback.

Balloon tooltip not display in systemtray

I set my NotifyIcon of the boot form as follows:
![
]1
thinking about getting something like:
But it doesn't show me anything when I hover over the icona in the systemtray. How come? what am I wrong
The balloon is only shown when you call NotifyIcon.ShowBalloonTip(timeout), not when you hover on the system tray icon, and it uses BalloonTipText and BalloonTipTile properties. You have to handle this method in some event or function.
For example, you could do this when you minimize the form:
NotifyIcon.Visible = True
NotifyIcon.ShowBalloonTip(2000, "MyApp", "The program is still running!", ToolTipIcon.Info)
When you hover on the icon and the icon is visible, instead, only a tooltip appears. The tooltip displays the string set in the Text property and doesn't use BalloonTipText and BalloonTipTile.
So you don't have to handle the hover, the ToolTip should automatically appear.
If the issue persists, try to set Visible = False in the designer in order to see whether setting Visible = True works and make sure that there isn't any instruction that throws exception before the ShowBalloonTip method.

Why is return from MessageBox.Show not "DialogResult.Cancel" when the close button is pressed?

I'm using the following code:
Dim Reply As DialogResult = MessageBox.Show("GOT IT!")
If Reply = DialogResult.OK Then '...`
When I click the Close button (red "X" in corner) the condition looking for DialogResult.OK still evaluates to true and when I check the Reply variable's value at runtime after clicking the close button it is 1 {OK}.
From the documentation on MessageBox Class it says:
Displays a message window, also known as a dialog box, which
presents a message to the user. It is a modal window, blocking other
actions in the application until the user closes it. A MessageBox can
contain text, buttons, and symbols that inform and instruct the user.
While I find the documentation on DialogBoxes a little convoluted and confusing, it appears to me (and i could be bery wrong) that the Close button should by default set the return to IDCancel which, I must assume is somehow parsed by the MessageBox class into DialogReturn.Cancel.
So why does MessageBox not show the return form the close button as DialogResult.Cancel??
This is all very confusing to me because it seems the MessageBox class is not consistent with other forms from within the same Systems.Windows.Forms namespace.
For instance, if we look at the documentation from the Form Class's .DialogResult method, it specifically tells us the return from the close button is DialogResult.Cancel:
When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X in the top-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel.
As already stated in the comments above, you could get IDCancel result when clicking the Close Red Button, only if you add a MessageBoxButtons enum that include the Cancel option For example MessageBoxButtons.OKCancel and others.
The MessageBox.Show method is indeed a wrapper around the WinApi MessageBox function. You could see this wrapping looking at the reference sources
The behavior of MessageBox.Show is different from the link that you have pointed. That one is relative to the WinForm engine and of course the behavior of the WinForm Form class is totally managed by the library to handle the scenarios presumed for a WinForm class.
In the WinApi documentation you could find a subtle reference in the section about the Return value where they talks about the behavior when the cancel button is present. Then trial and error confirms this assumption.
You need to pass in MessageBoxButtons as an override that includes a cancel button so like MessageBoxButtons.OKCancel.
Dim message As String = "GOT IT!"
Dim caption As String = "Fancy Caption"
Dim Reply As DialogResult = MessageBox.Show(message, caption, MessageBoxButtons.OKCancel)
If Reply = DialogResult.OK Then '...`
If you dont want the caption than skip it but you'll still need a comma, like:
MessageBox.Show("GOT IT!",,MessageBoxButtons.OKCancel)
See here for full enumeration of options for MessageBoxButtons.

RadioButtons Highlighting Incorrectly

On my form, I have 4 RadioButtons, each with its appearance set to Button. In my program, I change each of these RadioButton's ForeColour, BackColour and AutoCheck status, as below:
ARadioButton.AutoCheck = False
ARadioButton.BackColor = Color.FromKnownColor(KnownColor.ControlLightLight)
ARadioButton.ForeColor = Color.FromKnownColor(KnownColor.ControlDark)
However, later on, I reset these properties back to default:
ARadioButton.AutoCheck = True
ARadioButton.BackColor = DefaultBackColor
ARadioButton.ForeColor = DefaultForeColor
My issue is that instead of the entire button being highlighted, only the outside is, as shown in the images below.
Originally:
After changes are made and RadioButtons reset to default using code above:
I know this may seem trivial, but I would like the entire RadioButton to be highlighted when the user clicks on the RadioButton, not just the outside.
Is there a way I could somehow reset this?
Try setting the BackColor property to Color.Transparent

vb.net tabpage using a form for tabpanels issues

I have a simple vb.net form a tabpanel strip, and then a seperate form which is loaded for the tabpage.
Here is the code for the button that dynamically creates new tabs:
Dim tempTab As New TabPage
initTab(tempTab)
xt.TabPages.Add(tempTab)
xt.SelectedIndex = xt.TabCount - 1
Here is the code for the "initTab":
Dim tmpTab As New MainTab
tmpTab.Dock = DockStyle.Fill
tmpTab.Panel1.Dock = DockStyle.Fill
tab.Controls.Add(tmpTab)
tab.Text = "Untitled"
tab.Name = " "
I can easily set the focus of any tab by entering following which sets the focus for example to the last tab:
xt.SelectedIndex = xt.TabCount - 1
Now the issue is, how can I set the focus to a textbox on the custom form (in my example labeled "MainTab")? I've tried virtually everything I can google and I can't seem to find any example of how to setfocus or even set/get anything from the MainTab form.
Anyone can help me?
Erm, turning a form into a child control takes some surgery. You have to set its TopLevel property to false, hide the border, make it visible. I don't see it in the code snippet, is MainTab actually a form?
Anyhoo, you cannot use the Focus() method on a control until it is visible. Odds are good that it isn't visible yet in your code snippet. Use the Select() method instead. Say:
tmpTab.TextBox1.Select()
Or just set the TabIndex property of the first control that should get the focus to 0 in the designer.
xt.Controls(xt.SelectedIndex).Controls("TEXTBOXNAME").Focus()
Just make sure that you set the Name property of the textbox you want to have focus (in this case the name would be TEXTBOXNAME) if you do it like this.