Вывести окно на передний план в WPF - PullRequest
191 голосов
/ 03 ноября 2008

Как я могу перенести мое приложение 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 с таймером, он работает точно так, как ожидалось, поэтому я не уверен, почему он не работает в моем исходном случае.

Редактировать : Я делаю это в сочетании с глобальной горячей клавишей.

Ответы [ 18 ]

2 голосов
/ 11 ноября 2010

Чтобы показать ЛЮБОЕ открытое окно, импортируйте эти 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);
                }
2 голосов
/ 03 ноября 2008

Ну, я разобрался. Я звоню с помощью клавиатуры, используемой для реализации горячей клавиши. Вызов работает как положено, если я помещаю его в 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();
}
1 голос
/ 05 февраля 2017

Эти коды будут работать нормально все время.

Сначала установите активированный обработчик событий в 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();
}

Эти шаги будут хорошо работать и перенесут все остальные окна в окно их родителей.

1 голос
/ 28 февраля 2009

Проблема может заключаться в том, что поток, вызывающий ваш код из ловушки, не был инициализирован во время выполнения, поэтому вызов методов во время выполнения не работает.

Возможно, вы могли бы попытаться выполнить Invoke для перенаправления вашего кода в поток пользовательского интерфейса для вызова кода, который выводит окно на передний план.

0 голосов
/ 18 мая 2017

Я создал метод расширения, облегчающий повторное использование.

using System.Windows.Forms;
    namespace YourNamespace{
        public static class WindowsFormExtensions {
            public static void PutOnTop(this Form form) {
                form.Show();
                form.Activate();
            }// END PutOnTop()       
        }// END class
    }// END namespace

Позвоните в конструкторе форм

namespace YourNamespace{
       public partial class FormName : Form {
       public FormName(){
            this.PutOnTop();
            InitalizeComponents();
        }// END Constructor
    } // END Form            
}// END namespace
0 голосов
/ 24 апреля 2017

Не забудьте не помещать код, который показывает это окно, в обработчик PreviewMouseDoubleClick, поскольку активное окно переключится обратно на окно, обработавшее событие. Просто поместите его в обработчик событий MouseDoubleClick или прекратите пузыриться, установив для e.Handled значение True.

В моем случае я обрабатывал PreviewMouseDoubleClick для ListView и не устанавливал e.Handled = true, после чего он вызывал событие MouseDoubleClick с фокусом на исходном окне.

0 голосов
/ 13 апреля 2017

Просто хотел добавить другое решение этого вопроса. Эта реализация работает для моего сценария, где CaliBurn отвечает за отображение главного окна.

protected override void OnStartup(object sender, StartupEventArgs e)
{
    DisplayRootViewFor<IMainWindowViewModel>();

    Application.MainWindow.Topmost = true;
    Application.MainWindow.Activate();
    Application.MainWindow.Activated += OnMainWindowActivated;
}

private static void OnMainWindowActivated(object sender, EventArgs e)
{
    var window = sender as Window;
    if (window != null)
    {
        window.Activated -= OnMainWindowActivated;
        window.Topmost = false;
        window.Focus();
    }
}
0 голосов
/ 24 сентября 2014

Если вы пытаетесь скрыть окно, например, вы минимизируете окно, я обнаружил, что с помощью

    this.Hide();

будет правильно скрывать, а затем просто использовать

    this.Show();

снова покажет окно как самый верхний элемент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...