WPF: MainWindow черный фон - PullRequest
       25

WPF: MainWindow черный фон

0 голосов
/ 19 октября 2018

Я пытаюсь открыть MainWindow из системного трея, если приложение уже запущено, и пользователь попытался запустить новый экземпляр программы (один экземпляр)

Я следовал этому руководству: https://www.codeproject.com/Articles/32908/C-Single-Instance-App-With-the-Ability-To-Restore

Это прекрасно работало, если MainWindow свернуто, однако, когда я закрываю окно, которое просто скрываю, и заново открываю его из вновь созданного экземпляра, передавая сообщение (используя обработчик основного окна), Я открываю окно, но это черный экран.

Закрытие MainWindow:

private void main_Closing(object sender, System.ComponentModel.CancelEventArgs e) {

    // If the window is visible, then hide it
    if (IsVisible)
        Visibility = Visibility.Hidden;

    e.Cancel = true;

}

Отображение MainWindow с помощью обработчика MainWinow

public const int SW_SHOWNORMAL = 1;

[DllImportAttribute("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImportAttribute("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

public static void ShowToFront(IntPtr window) {
    ShowWindow(window, SW_SHOWNORMAL);
    SetForegroundWindow(window);
}

Как я вызываю его в моемMainWindow.xaml.cs

public void ShowWindow() {

    WinApi.ShowToFront(new WindowInteropHelper(this).Handle);

}

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

public void ShowWindow() {

    WinApi.ShowToFront(new WindowInteropHelper(this).Handle);

}

на

public void ShowWindow() {

    Visibility = Visibility.Visible;
    WindowState = WindowState.Normal;
}

Hoverver, мне все еще интересно, почемуОбработчик открыл мое главное окно с черным экраном?

Обычный: Normal View

Черный экран: enter image description here

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Я не могу точно вспомнить, когда и где, но сокрытие окна в основном заканчивает его жизнь, например, модальное окно.Когда мне нужно было сделать подобное, вместо того, чтобы скрывать или делать видимым ложное, я просто устанавливал для свойства LEFT окна какое-то непристойное отрицательное значение, чтобы пользователь не мог видеть.

Например, ваши фактические размеры окна 800x450.Я мог бы установить свою левую позицию на -900.Так как мое окно имеет наихудший случай шириной 800, переход влево на -900 не сделает его видимым, но также не освободит окно и его ресурсы.Поэтому, когда вы пытаетесь сбросить его видимость, вы просто устанавливаете его левую позицию обратно на 0. Теперь, если у пользователя есть несколько мониторов, это может быть другой проблемой ... возможно, установите левое значение на -4000.

0 голосов
/ 20 октября 2018

У меня нет прямого ответа на ваш вопрос, но я могу косвенно ответить на него, предложив более простой подход к вашей проблеме, чтобы избежать большинства WinForm, обработчиков ptr и импортировать все файлы DLL. Этот подход позволит вам работать почти только с кодом WPF, и я его протестировал, и проблема с цветом фона НЕ существует

Первое: в MainWindow.xaml.cs

  1. Сделать MainWindow синглтоном
  2. Подобно тому, что вы сделали, скрывайте MainWindow вместо его закрытия, когда пользователь пытается закрыть MainWindow.

Your MainWindow.xml.cs должен выглядеть так без вашего другого дополнительного кода:

using System.Windows;

namespace WPFSystemTray
{
public partial class MainWindow : Window
{
    private static MainWindow instance;

    public static MainWindow Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new MainWindow();
            }
            return instance;
        }
    }

    private MainWindow()
    {
        InitializeComponent();
        this.Closing += MainWindow_Closing;
    }

    private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (!App.IsExitApplication)
        {
            e.Cancel = true;
            this.Hide();
        }
    }
}
}

Second: Удалите следующий код из App.xaml.cs

StartupUri="MainWindow.xaml"

В-третьих: Добавьте следующие ссылки в ваш проект WPF

  1. System.Drawing
  2. System.Windows.Forms

References Screenshot

Четвертый: добавление значка в ресурсы

  1. Щелкните правой кнопкой мыши свой проект WPF и выберите «Свойства» ИЛИ , дважды щелкните «Свойства» в своем проекте WPF.
  2. Выбрать Ресурсы
  3. Выбрать ЗНАЧКИ
  4. Выбрать Рекламаd Ресурсы
  5. Выберите Добавить существующий файл ... , чтобы выбрать с вашего ПК ИЛИ выберите Добавить новый значок , чтобы создать новый.
  6. Если вы используете другой значок, убедитесь, что вы переименовали свой значок в Dapino-Summer-Holiday-Palm-tree.ico ИЛИ измените его в коде в App.xaml.cs Я получил свой значок теста по этой ссылке

ICONS Screenshot

Пятое: Добавить изображение в ресурсы

  1. Следуйте приведенным выше инструкциям (в четвертом)
  2. Обязательно измените Значки на Изображения
  3. ЕслиВы выбираете другое изображение, убедитесь, что вы переименовали его в palm-tree-icon.png ИЛИ убедитесь, что вы изменили имя в коде в App.xaml.cs Iполучил тестовый значок по этой ссылке

enter image description here

Шестое: App.xaml.cs

  1. Добавьте конструктор и метод запуска.
  2. Создайте экземпляр вашего приложения и приложения tray
  3. Добавлены два элемента в панель задач (имя приложения и выход)
  4. Один из элементов имеет значок, показывающий, как, если вы не знаете.

Ваш App.xaml.cs должен выглядеть следующим образом.

    using System;
    using System.Windows;

    namespace WPFSystemTray
    {
    public partial class App : Application
    {
        public static bool IsExitApplication;

    public App()
    {
        Startup += App_Startup;
    }

    private void App_Startup(object sender, StartupEventArgs e)
    {
        WPFSystemTray.MainWindow.Instance.Show();

        System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon();
        notifyIcon.DoubleClick += _notifyIcon_DoubleClick;
        notifyIcon.Icon = WPFSystemTray.Properties.Resources.Dapino_Summer_Holiday_Palm_tree;
        notifyIcon.Visible = true;

        CreateContextMenu(notifyIcon);
    }

    private void _notifyIcon_DoubleClick(object sender, EventArgs e)
    {
        ShowMainWindow();
    }

    private void CreateContextMenu(System.Windows.Forms.NotifyIcon notifyIcon)
    {
        if (notifyIcon != null)
        {
            notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip();
            notifyIcon.ContextMenuStrip.Items.Add("Application Name",
                WPFSystemTray.Properties.Resources.palm_tree_icon).Click 
                += NotifyIcon_ApplicationName_Click;

            notifyIcon.ContextMenuStrip.Items.Add("Exit").Click += NotifyIcon_Exit_Click;
        }
    }

    private void NotifyIcon_ApplicationName_Click(object sender, EventArgs e)
    {
        ShowMainWindow();
    }

    private void NotifyIcon_Exit_Click(object sender, EventArgs e)
    {
        IsExitApplication = true;

        MainWindow.Close();

        (sender as System.Windows.Forms.ToolStripItem).Owner.Dispose();
    }

    public void ShowMainWindow()
    {
        if (!MainWindow.IsVisible)
        {
            MainWindow.Show();
        }
        else
        {
            if (MainWindow.WindowState == WindowState.Minimized)
            {
                MainWindow.WindowState = WindowState.Normal;
            }

            MainWindow.Activate();
        }
    }
    }
    }

Сборка и тестирование

  1. В первом случае откроется MainWindow
  2. Чтобы сделать выбор в трее, щелкните правой кнопкой мыши значок и выберите (Имя приложения ИЛИ Выйти).
  3. Двойной щелчок по значку снова откроет приложение. Чтобы изменить его на один клик : измените notifyIcon.DoubleClick на notifyIcon.Click событие в App.xaml.cs
  4. Я пытался свести к минимуму изменения, чтобы вам было легче добавлять их в свой проект.
  5. Я надеюсь, что вы согласны с тем, что это намного проще и лучше, чем пример, которому вы следовали на codeproject.com.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...