I'm encountering strange behavior with forms on a c# 3.5 app. On a button click, my form1 hides itself, creates a new form2, and shows form2. Form1 also contains the event method triggered when form2 closes. Here's the code inside Form1:
Form2 form2;
void button1_Click(object sender, EventArgs e)
{
this.Hide();
form2 = new form2();
form2.Show();
form2.FormClosed += new FormClosedEventHandler(form2_FormClosed);
}
void form2_FormClosed(object sender, FormClosedEventArgs e)
{
form2.Dispose();
form2 = null;
this.Show();
}
Now, my problem is that sometimes when I open form2 (hiding form1), or when I close form2 (showing form1), the new form will come up on the screen for a blink and then hide itself. It's still open and I can click it from the taskbar to show it again, but the window itself is sent behind any other open windows. It looks like it opens up but minimizes instantly.
This behavior occurs randomly. Sometimes forms will open up and hide without a problem, but sometimes they'll lose focus over another window. I've tried using focus(), activate(), and topmost but all have failed to prevent the sudden hiding.
Does anyone know why is this happening and how to fix it?
Thanks.
You hide your form too soon. For a brief moment, your app has no window that can contain the focus. That forces Windows to go hunting for another window to give the focus to, it will pick one from another application. That window will now be the foreground window, your second form will not get the focus and appear lower in the Z-order. The fix is simple:
void button1_Click(object sender, EventArgs e)
{
form2 = new form2();
form2.Show();
form2.FormClosed += new FormClosedEventHandler(form2_FormClosed);
this.Hide(); // Moved
}
Related
Having a strange behaviour with my application whereby when navigation between web browser (or any other application) and clicking back into the application seems to open the wrong Form? So user literally has to make use of Tab window to open the correct Form.
For e.g. Form1 is the main form. User clicks a button which opens Form2. Form1 is hidden behind the scene while Form2 opens. Now if user goes to a different application e.g. browser and clicks back into the application Form1 is displayed and there is no other way of going back to Form2 without the Tab window?
I have used the .ShowDialog() property when opening Form2 which disabled the parent form Form1 but still seems to do it occasionally?!?
I have also set the ShowInTaskBar for Form2 to False so that there is one icon in taskbar for all forms.
Not really sure what can cause this behaviour to happen?
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.ShowDialog();
}
I think you need to tell Form2 who its owner form is.
Like this:
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Owner = this;
form2.ShowDialog();
}
see System.Windows.Forms for more information
When you open form2, you need set mdiParent of form1.
First, set form1 as "isMdiParent" to "true" in properties, and then use the follow code:
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.MdiParent = this;
form2.Show();
}
What's the proper way to close application with clicking on X in built in menu strip. Let's say that my Form1 opens Form2, when I close my Form2 my Form 1 stays open. What I want to achieve is that my application stops when I close my Form2. Does anybody know how to achieve this and how to reference it to X button on built in menu strip.
Try this:
Application.Exit();
In case it doesn't work, you have to provide more information and be more specific with code
In Form2 you could Register to the Closing Event in constructor something like this:
public Form2()
{
this.FormClosing += Form_OnClosing;
}
Then in the event close the Form1 and/or exit the application
private void Form_OnClosing(object sender, EventArgs args)
{
Application.OpenForms[0].Close();
Application.Exit();
Environment.Exit();
}
Try it
form2 F2 = new form2();
F2.ShowDialog()
I think you have a trouble with create new form children
I have two forms. The first is the parent and contains a reference to the second and a button:
public class Form1:Form {
private Form2 frm2;
private Button btnShow;
...
}
When I press the button frm2 must be shown (visible and in front of all other windows) and Form1 must hide.
When I press the closebox of frm2, frm2 must hide and Form1 must be shown (reverse).
I used the click event of btnShow to register a handle that all it does is:
private void click(object sender, EventArgs e)
{
Hide();
frm2.Show(this);
}
and in the FormClosing event of frm2:
private void byebye(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
Hide();
Owner.Show();
}
}
My codes works for 90% of the time but sometimes (i cannot specify when) the shown form
is not brought to front or loses focus (I am not sure about that i think the first).
What I am doing wrong. I've tried alternating the order of Show and Hide and using of a new reference instead of Owner, I also used Activate,BringToFront, Focus but with no success...
Why not simply:
{
Form2 fm = new Form2();
this.Visible = false;
fm.ShowDialog();
this.Visible = true;
}
Works for me.
Hide();
Owner.Show();
You are doing this the wrong way around. For a split second, there's no single window left in your application that can receive the focus. The Windows window manager is forced to find another window to give the focus to. Which will be the window of another application. With good odds that this is a large enough window to cover your own. Your Show() call will thus make your window visible again, but now underneath that window that got moved into the foreground. This doesn't always happen btw, the window manager appears to use a small timeout. The longer the owner has been hidden, the greater the odds that its code has been swapped out and that showing it takes more time, thus tripping the timeout.
The workaround is simple, just swap the two statements so you'll always have window that can be focused. Fix:
Owner.Show();
Hide();
In my C# application, I have the following method that is called when the main form closes.
private void FormMain_Closing(object sender, FormClosingEventArgs e)
{
// Show this dialog when the user tries to close the main form
Form testForm = new FormTest();
testForm.StartPosition = FormStartPosition.CenterParent;
testForm.ShowDialog();
}
This creates a dialog window that will show when the main form is closing. However, my issue is that when the user closes testForm, the main form closes immediately after. I've tried all sorts of variants of e.Cancel = true; and such, and still cannot cancel the main form closing.
Any ideas?
Edit: it looks like I'm running into an issue using two ShowModal()'s in succession. Looking into the issue...
Edit: Used this.DialogResult = DialogResult.None; and it seems to have fixed my problem. It is apparently a known issue in WinForms when opening a modal dialog from a modal dialog.
This code works fine with me. I think there is a problem in another part of your code.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Form testForm = new FormTest();
testForm.StartPosition = FormStartPosition.CenterParent;
testForm.ShowDialog();
e.Cancel = testForm.DialogResult == DialogResult.Cancel;
}
This could to be handled by the children too from the docs:
If a form has any child or owned
forms, a FormClosing event is also
raised for each one. If any one of the
forms cancels the event, none of the
forms are closed. Therefore the
corresponding FormClosed events are
not sent to any of the forms.
I know that you mention in your question that you have tried to use 'e.Cancel = true;' However, the following code works in my environment (.NET 4.0, Visual Studio 2010, Windows 7):
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
// Show this dialog when the user tries to close the main form
Form testForm = new FormTest();
testForm.StartPosition = FormStartPosition.CenterParent;
testForm.ShowDialog();
e.Cancel = true;
}
If this doesn't work in your case you may have other event handlers at work. In that case try this code in a newly generated Windows Forms Application.
I am using Visual Studio 2010, C# .NET 4.0. I have 3 forms: Form1, Form2, Form3.
In Form1 I have a button to open Form2:
private void button1_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
f.Show();
}
In Form2 I have a private Form3 variable always pointing to the same Form3:
private Form3 f = new Form3();
And a button to open it as a dialog:
private void button1_Click(object sender, EventArgs e)
{
f.ShowDialog();
}
In Form3 I just have a button to hide the form:
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
}
The problem is that having the situation that Form2 is in front of Form1, and Form3 in front of Form2, when I click the button of Form3 to hide it, it not only hides itself but sends Form1 to the back of all of the other Windows.
This only happens when there is a window of another program (such as Windows Explorer) in the background of Form1. It seems like a bug. What do you think?
Yes, this cannot work properly by design. A dialog disables all of the windows that your program displays. So that it is modal. When you hide the dialog, there are no windows left that can get the focus. Windows is forced to find another window to give the focus to. That will be a window owned by another application. Your own windows will now hide behind it.
There are more side effects, the dialog will also close. Necessary because otherwise the user can never get back to your program anymore since all windows are disabled. This is all unsurprising behavior. Bug would be a strong word, but it would of course work better if it first re-enabled all windows before closing the dialog. But closing the dialog is already undesirable behavior.
Don't call Hide() for a dialog. Just set the DialogResult property to DialogResult.Cancel to achieve the exact same effect, minus the focus problem. You do have to reset it back to None if you want to display the dialog again. That's a real bug.
By the documentation. Form.Close method doesn't dispose forms shown by Form.ShowDialog method. Quote:
The two conditions when a form is not disposed on Close is when (1) it is part of a multiple-document interface (MDI) application, and the form is not visible; and (2) you have displayed the form using ShowDialog. In these cases, you will need to call Dispose manually to mark all of the form's controls for garbage collection.
So, maybe there are ways to return focus to your application (e.g. via Windows API). But it is much more convenient to call Form.Close manually on dialog windows.