BringToFront()
is a good solution, but it flickers a little, when I call it twice (on second form and then again on the first form). I finally used a external method from user32.dll
called SetWindowPos
, to make a new bringToFront method of my own, that doesn't flicker at all and gives me the feeling that both forms are linked with each other. Here it goes (Everything with X is a custom class/enum/struct) :
public partial class XForm : Form
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, XWindowPositionFlag uFlags);
public void bringToFront()
{
SetWindowPos(this.Handle, XFormZIndex.Top, 0, 0, 0, 0,
XWindowPositionFlag.SWP_NOMOVE | XWindowPositionFlag.SWP_NOSIZE | XWindowPositionFlag.SWP_NOACTIVATE);
}
}
where
public struct XFormZIndex
{
public static IntPtr
NoTopMost = new IntPtr(-2),
TopMost = new IntPtr(-1),
Top = new IntPtr(0),
Bottom = new IntPtr(1);
}
[Flags]
public enum XWindowPositionFlag : uint
{
SWP_ASYNCWINDOWPOS = 0x4000,
SWP_DEFERERASE = 0x2000,
SWP_DRAWFRAME = 0x0020,
SWP_FRAMECHANGED = 0x0020,
SWP_HIDEWINDOW = 0x0080,
SWP_NOACTIVATE = 0x0010,
SWP_NOCOPYBITS = 0x0100,
SWP_NOMOVE = 0x0002,
SWP_NOOWNERZORDER = 0x0200,
SWP_NOREDRAW = 0x0008,
SWP_NOREPOSITION = 0x0200,
SWP_NOSENDCHANGING = 0x0400,
SWP_NOSIZE = 0x0001,
SWP_NOZORDER = 0x0004,
SWP_SHOWWINDOW = 0x0040,
}
and then in FormPair
public partial class XFormPair
{
// properties
public XForm leftForm { get; set; }
public XForm rightForm { get; set; }
// events
private void rightFormActivated(object sender, EventArgs e)
{
leftForm.bringToFront();
rightForm.bringToFront();
}
private void leftFormActivated(object sender, EventArgs e)
{
rightForm.bringToFront();
leftForm.bringToFront();
}
}