Способ 1
В классе Window1 найдите объявление поля wnd2 (строка: Window wnd2; ), щелкните на поле wnd2 правой кнопкой мыши и выполните команду контекстного меню Refactor/Encapsulate Field
Появится окно Encapsulate Field, предлагающее обернуть поле в общедоступное свойство с именем Wnd2
Скажите OK и оболочка создаст следующий код свойства
public static Window Wnd2
{
get { return Window1.wnd2; }
set { Window1.wnd2 = value; }
}
Аксессор get нам не нужен, поскольку в клиенте Window2 при закрытии окна мы будем поле wnd2 только обнулять через свойство Wnd2, поэтому get следует удалить.
Внесите в класс Window1 следующий окончательный код реализации первого способа
// Предотвращение повторного открытия окна: Способ 1
static Window wnd2;
public static Window Wnd2
{
set { Window1.wnd2 = value; }
}
// Обработчик двойного щелчка
private void Show_Window2(object sender, MouseButtonEventArgs e)
{
if (wnd2 == null)
{
wnd2 = new Window2();
wnd2.Show();
}
else
wnd2.Activate();// Сдвинуть на передний план
}
Модифицируйте класс Window2 следующим образом
public partial class Window2 : Window
{
public Window2()
{
// Инициализация разметочной части
InitializeComponent();
// Корректировка заголовка окна
this.Title += "=\"Так голодают буржуины!\"";
// Дочернее окно не отображать в панели задач ОС
this.ShowInTaskbar = false;
// Регистрация обработчика
this.Closed += new EventHandler(Window2_Closed);
}
private void Window2_Closed(object sender, EventArgs e)
{
Window1.Wnd2 = null; // Для предотвращения повторного запуска
GC.WaitForFullGCComplete(); // Ждать завершения сборки мусора
GC.Collect(); // Начать сборку мусора
}
}
Здесь мы немного перестарались и ввели еще принудительный вызов сборщика мусора. Это необязательно, так как запуск механизма освобождения брошенных ссылок активизирует сама среда исполнения и в том случае, когда заканчивается выделенная домену приложения оперативная память.
Запустите приложение и убедитесь, что обработчик создания дочернего окна по двойному щелчку теперь работает правильно
Способ 2
В разметку файла Window2.xaml добавьте определение свойства Name окна Window2 для его идентификации в коллекции приложения
<Window x:Class="WpfApp3.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Window_2"
Title="Дочернее окно Window2: Работа объекта ImageDrawing через разметку"
SizeToContent="WidthAndHeight"
ResizeMode="NoResize"
Background="Green"
>
...................................
</Window>
Модифицируйте обработчик контекстного меню в файле Window1.xaml.cs следующим образом
// Предотвращение повторного открытия окна: Способ 2
// Обработчик контекстного меню
private void Create_Window2(object sender, RoutedEventArgs e)
{
bool windowExists = false;
foreach (Window window in Application.Current.Windows)
{
if (window.Name == "Window_2")
{
windowExists = true;
window.Activate();// Сдвинуть на передний план
break;
}
}
if (!windowExists)
{
wnd2 = new Window2();
wnd2.Show();
}
}
Запустите приложение и убедитесь, что и этот обработчик блокирования повторного запуска теперь тоже работает правильно
Разберитесь с кодом
