How to focus a control in an MDIParent when all child windows have closed?
I have a control in my parent mdi form which I wish to be given the focus if all mdi children have closed. I've tried hooking into the child form's FormClosed event and setting the focus from there but when I test it, my control is not left with focus when I close the mdi child.
Can anyone tell me what I'm missing?
In the sample below, "first focus" gets hit and does its job correctly (if I comment out the first focus line, my tree does not get focus on startup, so it must be doing its job, right?) Unfortunately, even though "second focus" gets hit, my tree does not end up with the focus when I close the child window.
Has focus on startup.
Has focus http://www.programmingforpeople.com/images/stackoverflow/focus1.PNG
Not focussed after closing child window.
No focus http://www.programmingforpeople.com/images/stackoverflow/focus2.PNG
Sample
using Sys开发者_运维知识库tem;
using System.Windows.Forms;
namespace mdiFocus
{
class ParentForm : Form
{
public ParentForm()
{
IsMdiContainer = true;
tree = new TreeView();
tree.Nodes.Add("SomeNode");
tree.Dock = DockStyle.Left;
Controls.Add(tree);
}
protected override void OnShown(EventArgs e)
{
Form child = new Form();
child.MdiParent = this;
child.Show();
child.FormClosed += new FormClosedEventHandler(child_FormClosed);
tree.Focus(); // first focus works ok
}
void child_FormClosed(object sender, FormClosedEventArgs e)
{
tree.Focus(); // second focus doesn't seem to work, even though it is hit :(
}
TreeView tree;
}
static class Program
{
[STAThread]
static void Main()
{
Application.Run(new ParentForm());
}
}
}
I repro, smells like the WF logic that hunts for a focusable item is running after the event and messes up the focus. These kind of problems can be elegantly solved by running code after the event is processed by using Control.BeginInvoke(). This worked well:
private void toolStripButton1_Click(object sender, EventArgs e) {
Form child = new Form2();
child.MdiParent = this;
child.FormClosed += new FormClosedEventHandler(child_FormClosed);
child.Show();
}
void child_FormClosed(object sender, FormClosedEventArgs e) {
if (this.MdiChildren.Length == 1) {
this.BeginInvoke(new MethodInvoker(() => treeView1.Focus()));
}
}
精彩评论