When using the Focus()
method, the targeted form acquire focus but is also brought in front of the other forms.
Is there a way to avoid this z-order modification ?
Here is a short example :
class MyForm : Form
{
static void Main(string[] args)
{
MyForm f1 = new MyForm()
{
Text = "f1"
};
f1.Show();
MyForm f2 = new MyForm()
{
Text = "f2"
};
f2.Show();
Button b1 = new Button();
b1.Click += (sender, e) => f2.Focus();
f1.Controls.Add(b1);
Button b2 = new Button();
b2.Click += (sender, e) => f1.Focus();
f2.Controls.Add(b2);
Application.Run(f1);
}
}
When clicking the button in f1
, f2
will gain focus but will also come in front of f1
(which is the thing I'd like to avoid).
Not really sure it's the best way to do it, but I ended up using the owner property :
class MyForm : Form
{
public const int WM_NCLBUTTONDOWN = 0x00A1;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCLBUTTONDOWN:
TakeFocus();
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
private void TakeFocus()
{
if (Owner == null && OwnedForms.Length > 0)
{
Form tmp = OwnedForms[0];
tmp.Owner = null;
Owner = tmp;
}
BringToFront();
}
static void Main(string[] args)
{
MyForm f1 = new MyForm()
{
Text = "f1",
};
f1.Show();
MyForm f2 = new MyForm()
{
Text = "f2",
};
f2.Owner = f1;
f2.Show();
Button b1 = new Button();
b1.Click += (sender, e) =>
{
f1.TakeFocus();
};
f1.Controls.Add(b1);
Button b2 = new Button();
b2.Click += (sender, e) =>
{
f2.TakeFocus();
};
f2.Controls.Add(b2);
Application.Run(f1);
}
}
In this example, a window gain focus without going in front of the other window when clicking on it's client area. If you click on the non-client area (titlebar and borders) or the button the form gain focus and is brought in front.