I have a singletone instance of window in my WPF application (which is not main window). Due to it's structure, this window only closes when the main window is closed; If the user closes this window, it becomes hidden. When I click on some image in main window, I want the following behaviour of second window:
- If window is hidden and image was clicked, I want to show it on top of all windows (but NOT by setting
Topmost = true
, I want just SHOW it on top, rather than fix it on top forever). - If window is shown on top, there is nothing to do.
- If window is open, but covered by other window or minimized, I also want to show it on top only ONCE.
What I have at the moment:
// In some application class
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
if (App.Current.MyWindow == null)
{
App.Current.MyWindow = WeightImageWindowView.Instance;
}
App.Current.MyWindow.ShowTop();
}
...
// in MyWindow class
public void ShowTop()
{
this.Topmost = true;
this.Show();
if (this.WindowState == WindowState.Minimized)
{
this.WindowState = WindowState.Normal;
}
var a = this.Activate();
var b = this.Focus();
this.Topmost = false;
}
I tried to use all these commands one by one, in pairs and all together, but didn't get the behaviour described above.
CodePudding user response:
WndHelper.BringToFront(this);
Use the helper below and just call bringtofront
public class WndHelper
{
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd);
public static void HideWindow(Window window)
{
var wih = new WindowInteropHelper(window);
WndHelper.ShowWindow(wih.Handle, 0);
}
public static void BringToFront(Window window)
{
var wih = new WindowInteropHelper(window);
BringToFront(wih.Handle);
}
//If the window is minimized, then Restore must be run first
//Windows that are in the background are enough to set as Foreground
public static void BringToFront(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
return;
try
{
if (WndHelper.IsIconic(hWnd)) //the window is minimized
{
WndHelper.ShowWindow(hWnd, 9); // SW_RESTORE = 9
WndHelper.SetForegroundWindow(hWnd); // set window to foreground
}
else
WndHelper.SetForegroundWindow(hWnd);
}
catch { }
}
}
CodePudding user response:
Thanks @Villiam! I found the following solution:
- Set
MyWindow.ShowActivated = true
; - Rewrite
ShowTop
method as:
public void ShowTop()
{
if (this.WindowState == WindowState.Minimized)
{
this.WindowState = WindowState.Normal;
}
this.Topmost = true;
this.Show();
this.Topmost = false;
}