c# set focus on multiple child forms - c#

I have a main form and then open one childdialog (nr 1) and on that I open an other childdialog (nr 2).
When I then open up that main form from another application the focus is set on the last child (nr 2), when I press enter the focus is set on the main form, I want the focus to go on child nr 1.
To open up the main form I use Activate();
Then in OwnedForms I have an array of children.
Activate();
if(OwnedForms.Any())
{
OwnedForms.Last().Focus();
}
When I choose to close that form that has focus, the focus will go to the main form instead of the next child (last -1) in the OwnedForms array.
Tried bringtofront and sendtoback without any success.

Make sure that the form's parent is set.
OwnedForms.Last().Parent = this;
Also you may want to look into .Show() vs .ShowDialog() on the forms.
It seems like you might prefer .ShowDialog() in your case if you are not already doing so.

Related

How do I get a user control to be closed when I close a specific form?

When I open from the main screen of the application a child form I also display a user control that should be displayed until the child form is closed or the user closes it. If I set the child form to be usercontrol's parent, the user control is not displayed (so the parent of the user control is the desktop). I used SetWindowPos with HWND_TOPMOST and I get the correct behaviour. now when I close the child form I want the usercontrol to close as well. Do you know what I shoud do to get this?
thanks,
When you Show() the child you can also subscribe to it's Closed or Closing event and use that to properly close the UC.
var f = new ChildForm();
// show userctl
f.Closed += MainForm_ChildClosed_Handler;
void MainForm_ChildClosed_Handler(object s, EventArgs e)
{
// close/hide userctl
}
If you keep a reference towards your usercontrol, you should be able to Close (or even Dispose) it from the Closingevent of his parent.
I don't know what you are doing, a UserControl is meant to be a child control, it should be embedded in a Form. It is technically possible to turn a UC into a top level window (like Form), you'd have to set the TopLevel property to True. That however isn't very productive, the window doesn't have the chrome to make it friendly to use. It is missing the title bar, no easy way for the user to move it around, minimize it, close it. And no easy way to solve focus problems, it can disappear behind another window with no easy way for the user to bring it back to the front. Making it top-most is a hack of sorts to get at least the focusing problem solved, but at rather a deer cost.
Just use the UC as it was intended to be used: put it inside a form. That form should probably be the child form you open. It could also be a third form, say a tool window. Use the Show(owner) overload to keep its Z-order in check and cannot do the disappearing act. That also causes it to automatically close when the owner closes.

Showing a form via Form.Show is not given focus?

I two forms, Form1, and a UserControl which hosts Form2. Within that UserControl on Form1 I call Form2.Show();. I have also tried Form2.Show(this);. Either way, the focus is not given to the form. I have to click once within the new form to give it focus, and then I can click items within that form.
I figured that control is passing back to my main control/form, and thus the focus is getting lost. So I am waiting until Form2 is closed via:
while (form2.Visible == true)
{
System.Threading.Thread.Sleep(100);
Application.DoEvents();
}
This seems to work. However after I close the form, now the reverse holds true. Form1 is not given focus (even if I call this.Focus()) until I click once within the main form window.
Any ideas how to handle this properly. I want to show a child form (modeless) and immediatley be able to click on it, and when that form is closed, immediately be able to take action back on the parent form.
You should probably use .ShowDialog(), this can also be extended to give your response on if the user performed Form2's operation properly or aborted early.
This does make the form locked in focus up front and will halt your code execution on the first form till that form is closed.
use this.Activate(); in place of this.Focus();
Not sure I follow completely, but from your UC try opening Form2 like this:
form2.Show(Parent);
This should specify the UC's Parent form as form2's owner.
This came from the fact that I was overriding WndProc in order to display the form. When I received the CBN_DROPDOWN message, I would display the form. I fixed this by instead Invoke'ing the method that shows the form and it fixed it.
case CBN_DROPDOWN:
Invoke(new MethodInvoker(Show_DropDown));
return;

Closing One Form From Another Form?

I have a little application that creates alerts whenever a change to a database is made.
I have a few options in the alert form that pops up.
One of the options opens another form (a child form) asking the user for further information.
When the child form gets the necessary information from the user, I want it to close as well as the parent form. So far, I only know how to close the child form, but not the parent form.
Parent form > Opens child form
Child gathers information > User clicks ok in child > child closes, parent closes
^this is what I want
I just don't have the brain power to think about how to communicate across forms to accomplish closing the parent form.
Any help would be much appreciated. Actually, it would be super appreciated. If I could learn how to make my forms communicate with each other, I could really do a lot of damage (in a good way 8D ).
In the parent form, you can do something like this:
ChildForm f = new ChildForm();
f.FormClosed += (o,e) => this.Close();
f.Show();
Try this in the parent form:
using (var childForm = new ChildForm())
{
if (childForm.ShowDialog() == DialogResult.OK)
{
Close();
}
}
Your child form should return a DialogResult by clicking buttons (OK or Cancel) and/or setting the AcceptButton and CancelButton properties in the designer.

C# - How to deal with 2 "TopMost" Forms?

I have a parent form that is set to be TopMost and then I have another form that opens when a button is clicked. This child form is also set to be TopMost. The first issue I had was that when I opened the child form, the application would basically freeze because you couldn't access anything. I decided that instead of using ShowDialog() to open the child form, I would use Show(this). This did fix the initial problem but now I have a new one. The childforms start postition is set to be CenterParent and when I use Show(this), it doesn't work. Is there any way I can make the childform open while both it and the parent form are set to topmost while having the childforms start position set to CenterParent? Thank you.
I've find something useful to share with you, guys. Instead following code
form2.TopMost = true;
use this code in main form:
form2.Owner = this;
If you use Form.TopMost property, the form will overlap all other non-topmost forms, but also those from other applications. Instead of this, set the Form.Owner property to the parent form – the one which should be under the form (e.g. the main form).
G00d luck :)
You could try clearing the TopMost property of the parent form for the duration that the child form is visible.
This would solve the problem of which form should be top most, as there will only ever be one.
Hmm. I've created To forms. Then i set TopMost = true on both. The i add button to first and wrote
new Form2().ShowDialog();
And all just fine. Form2 active and clickable. Form1 not since ShowDialog was called
And second variant works fine. Form2 opened in center of the screen.
May be i misunderstood something?

How can you determine whether a form has been closed by the user or by your code?

I have a form (let's call it parent form), from which another "always on top but not modal" form can be loaded (Like a dialog but not a dialog - user can leave the new "child form" where it is and continue to work on the parent form).
The first time the user opens that child form some data is loaded and displayed. Should they close the form, I actually intercept the close and simply hide the form - so that next time they open it, we don't have to reload the data (it is not data that changes very much if at all).
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.Hide();
}
Later, when the parent form is closed, I want to force the child form to close properly - running some code in it's base form to store its location and size for next time.
Currently I call childForm.Dispose() from the parent form which cleans thing up nicely, but doesn't give me much control.
However, if I call the childForm.Close() method, the e.CloseReason is still "CloseReason.UserClosing".
Is there a way to distinguish between the user closing the form and my code (in the parent form) closing it?
Just add a special "ReallyClose()" method that does your cleanup and is called when you really want to close the form.

Categories