我如何把我的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,它完全按照预期工作,所以我不确定为什么它在我原来的情况下不工作。

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


当前回答

如果你需要窗口在第一次加载时在前面,那么你应该使用以下方法:

private void Window_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
}

private void Window_Initialized(object sender, EventArgs e)
{
    this.Topmost = true;
}

或者重写方法:

protected override void OnContentRendered(EventArgs e)
{
    base.OnContentRendered(e);
    Topmost = false;
}

protected override void OnInitialized(EventArgs e)
{
    base.OnInitialized(e);
    Topmost = true;
}

其他回答

要显示当前打开的任何窗口,请导入这些DLL:

public partial class Form1 : Form
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);
    [DllImportAttribute("User32.dll")]
    private static extern int SetForegroundWindow(int hWnd);

我们搜索指定标题的应用程序(写标题没有第一个字母(索引> 0))

  foreach (Process proc in Process.GetProcesses())
                {
                    tx = proc.MainWindowTitle.ToString();
                    if (tx.IndexOf("Title of Your app WITHOUT FIRST LETTER") > 0)
                    {
                        tx = proc.MainWindowTitle;
                        hWnd = proc.Handle.ToInt32(); break;
                    }
                }
                hWnd = FindWindow(null, tx);
                if (hWnd > 0)
                {
                    SetForegroundWindow(hWnd);
                }

我知道这个问题相当古老,但我刚刚遇到了这个精确的场景,并想分享我实现的解决方案。

正如本页的评论中提到的,提出的几个解决方案不能在XP上工作,而我需要在我的场景中支持XP。虽然我同意@Matthew Xavier的观点,他认为这是一种糟糕的用户体验实践,但有时这完全是一种合理的用户体验。

将WPF窗口带到顶部的解决方案实际上是由我用来提供全局热键的相同代码提供给我的。Joseph Cooney的一篇博客文章包含了他的代码示例的链接,其中包含原始代码。

我已经清理并修改了一些代码,并将其实现为System.Windows.Window的扩展方法。我已经在XP 32位和Win7 64位上进行了测试,两者都能正常工作。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace System.Windows
{
    public static class SystemWindows
    {
        #region Constants

        const UInt32 SWP_NOSIZE = 0x0001;
        const UInt32 SWP_NOMOVE = 0x0002;
        const UInt32 SWP_SHOWWINDOW = 0x0040;

        #endregion

        /// <summary>
        /// Activate a window from anywhere by attaching to the foreground window
        /// </summary>
        public static void GlobalActivate(this Window w)
        {
            //Get the process ID for this window's thread
            var interopHelper = new WindowInteropHelper(w);
            var thisWindowThreadId = GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);

            //Get the process ID for the foreground window's thread
            var currentForegroundWindow = GetForegroundWindow();
            var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);

            //Attach this window's thread to the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);

            //Set the window position
            SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

            //Detach this window's thread from the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);

            //Show and activate the window
            if (w.WindowState == WindowState.Minimized) w.WindowState = WindowState.Normal;
            w.Show();
            w.Activate();
        }

        #region Imports

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

        [DllImport("user32.dll")]
        private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        #endregion
    }
}

我希望这段代码能帮助其他遇到这个问题的人。

我有一个类似的问题与WPF应用程序,从访问应用程序通过Shell对象调用。

我的解决方案如下-工作在XP和Win7 x64应用程序编译到x86目标。

我宁愿这样做,而不是模拟一个alt选项卡。

void Window_Loaded(object sender, RoutedEventArgs e)
{
    // make sure the window is normal or maximised
    // this was the core of the problem for me;
    // even though the default was "Normal", starting it via shell minimised it
    this.WindowState = WindowState.Normal;

    // only required for some scenarios
    this.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();
}

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

如果你需要窗口在第一次加载时在前面,那么你应该使用以下方法:

private void Window_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
}

private void Window_Initialized(object sender, EventArgs e)
{
    this.Topmost = true;
}

或者重写方法:

protected override void OnContentRendered(EventArgs e)
{
    base.OnContentRendered(e);
    Topmost = false;
}

protected override void OnInitialized(EventArgs e)
{
    base.OnInitialized(e);
    Topmost = true;
}