我如何把我的WPF应用程序带到桌面的前面?到目前为止,我尝试过:

SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);

SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);

其中没有一个在做这项工作(Marshal.GetLastWin32Error()表示这些操作成功完成,并且每个定义的P/Invoke属性都具有SetLastError=true)。

如果我创建一个新的空白WPF应用程序,并使用计时器调用SwitchToThisWindow,它完全按照预期工作,所以我不确定为什么它在我原来的情况下不工作。

编辑:我这样做与一个全局热键。


当前回答

既然这是个热门话题…以下是对我有效的方法。如果我不这样做,我就会得到错误,因为如果你看不到窗口,Activate()就会出错。

Xaml:

<Window .... 
        Topmost="True" 
        .... 
        ContentRendered="mainWindow_ContentRendered"> .... </Window>

后台代码:

private void mainWindow_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
    this.Activate();
    _UsernameTextBox.Focus();
}

这是唯一能让窗口在顶部显示的方法。然后激活它,这样你就可以在框中输入,而不必用鼠标设置焦点。control.Focus()不会工作,除非窗口是Active();

其他回答

我想到了一个变通办法。我从一个用于实现热键的键盘钩子进行调用。如果我把它放入一个暂停的BackgroundWorker中,调用就会像预期的那样工作。这是一个拼凑,但我不知道为什么它不工作最初。

void hotkey_execute()
{
    IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(delegate
        {
            Thread.Sleep(10);
            SwitchToThisWindow(handle, true);
        });
    bg.RunWorkerAsync();
}

我知道这是一个很晚的答案,也许对研究人员有帮助

 if (!WindowName.IsVisible)
 {
     WindowName.Show();
     WindowName.Activate();
 }

这些代码在任何时候都能正常工作。

首先在XAML中设置激活事件处理器:

Activated="Window_Activated"

在主窗口构造函数块中添加以下行:

public MainWindow()
{
    InitializeComponent();
    this.LocationChanged += (sender, e) => this.Window_Activated(sender, e);
}

并在激活事件处理程序中复制以下代码:

private void Window_Activated(object sender, EventArgs e)
{
    if (Application.Current.Windows.Count > 1)
    {
        foreach (Window win in Application.Current.Windows)
            try
            {
                if (!win.Equals(this))
                {
                    if (!win.IsVisible)
                    {
                        win.ShowDialog();
                    }

                    if (win.WindowState == WindowState.Minimized)
                    {
                        win.WindowState = WindowState.Normal;
                    }

                    win.Activate();
                    win.Topmost = true;
                    win.Topmost = false;
                    win.Focus();
                }
            }
            catch { }
    }
    else
        this.Focus();
}

这些步骤将工作良好,并将前面所有其他窗口进入他们的父母窗口。

记住不要把显示该窗口的代码放在PreviewMouseDoubleClick处理程序中,因为活动窗口将切换回处理该事件的窗口。 只要把它放在MouseDoubleClick事件处理程序中,或者通过设置e.Handled为True来停止冒泡。

在我的情况下,我正在处理一个列表视图上的PreviewMouseDoubleClick,并没有设置e.Handled = true,然后它会引发MouseDoubleClick事件,将焦点集中到原始窗口。

让这个快速复制粘贴- 使用这个类的DoOnProcess方法将进程的主窗口移动到前台(但不是从其他窗口窃取焦点)

public class MoveToForeground
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);

    const int SWP_NOMOVE        = 0x0002;
    const int SWP_NOSIZE        = 0x0001;            
    const int SWP_SHOWWINDOW    = 0x0040;
    const int SWP_NOACTIVATE    = 0x0010;
    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    public static void DoOnProcess(string processName)
    {
        var allProcs = Process.GetProcessesByName(processName);
        if (allProcs.Length > 0)
        {
            Process proc = allProcs[0];
            int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
            // Change behavior by settings the wFlags params. See http://msdn.microsoft.com/en-us/library/ms633545(VS.85).aspx
            SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
        }
    }
}

HTH