Ответ 1
Если вам действительно необходимо обеспечить соблюдение одного экземпляра окна, то статический экземпляр (какой-то вкус того, что у вас есть) с помощью метода создания factory, безусловно, является жизнеспособным вариантом, очень похожим на один экземпляр DataContext при работе с базы данных.
Вы также можете написать свой собственный класс WindowManager, хотя это кажется излишним и, по сути, будет одним и тем же (кроме методов factory будет в одном классе).
Однако, перечитывая свой пост, я задаюсь вопросом, является ли это случаем отсутствия леса для деревьев. Ваше упоминание о вашем SettingsWindow, которое, в свою очередь, вызывает AccountWindow, заставляет меня думать, что вы просто должны использовать ShowDialog(). Это открывает окно модально, то есть не может быть никакого взаимодействия с вызывающим окном (или любым другим окном в вашем приложении). Вы просто установите свойство в этом диалоговом окне, установите для параметра DialogResult значение true, когда нажата кнопка OK, и прочитайте это свойство в родительском окне.
В принципе, вы просто используете ShowDialog, как это. Я оставляю много деталей реализации, насколько это необходимо для привязки к жесткому кодированию. Эти детали не так важны, как просто увидеть, как работает ShowDialog.
Для простоты предположим, что у вас есть класс MyAppOptions, который хорошо отражает варианты вашего приложения. Для большей простоты я оставлю большинство деталей реализации, но скорее всего это будет реализовывать INotifyPropertyChanged, методы, поля и свойства и т.д.
public class MyAppOptions
{
public MyAppOptions()
{
}
public Boolean MyBooleanOption
{
get;
set;
}
public String MyStringOption
{
get;
set;
}
}
Затем сделаем это простым и предположим, что вы хотите показать диалог "Параметры", когда вы нажимаете кнопку в каком-то окне. Кроме того, я буду предполагать, что есть переменные, которые были установлены с вашими параметрами, которые были загружены при запуске.
void btnOptions_Click(object sender, RoutedEventArgs e)
{
MyAppOptions options = new MyAppOptions();
options.MyBooleanOption = mSomeBoolean;
options.MyStringOption = mSomeString;
OptionsDialog optionsDialog = new optionsDialog(options);
if (optionsDialog.ShowDialog() == true)
{
// Assume this function saves the options to storage
// and updates the application (binding) appropriately
SetAndSaveOptions(optionsDialog.AppOptions);
}
}
Теперь предположим, что OptionsDialog - это окно, которое вы создали в своем проекте, и у него есть CheckBox, связанный с MyBooleanOption и TextBox для MyStringOption. Он также имеет кнопку "ОК" и кнопку "Отмена". Скорее всего, код будет использовать Binding, но теперь мы будем жестко кодировать значения.
public class OptionsDialog : Window
{
public OptionsDialog(MyAppOptions options)
{
chkBooleanOption.IsChecked = options.SomeBooleanOption;
txtStringOption.Text = options.SomeStringOption;
btnOK.Click += new RoutedEventHandler(btnOK_Click);
btnCancel.Click += new RoutedEventHandler(btnCancel_Click);
}
public MyAppOptions AppOptions
{
get;
set;
}
void btnOK_Click(object sender, RoutedEventArgs e)
{
this.AppOptions.SomeBooleanOption = (Boolean) chkBooleanOption.IsChecked;
this.AppOptions.SomeStringOption = txtStringOption.Text;
// this is the key step - it will close the dialog and return
// true to ShowDialog
this.DialogResult = true;
}
void btnClose_Click(object sender, RoutedEventArgs e)
{
// this will close the dialog and return false to ShowDialog
// Note that pressing the X button will also return false to ShowDialog
this.DialogResult = false;
}
}
Это довольно простой пример в отношении деталей реализации. Поиск в Интернете для ShowDialog для получения более подробной информации. Важные ключи для запоминания:
- ShowDialog открывает окно модально, что означает, что это единственное окно в вашем приложение, которое может взаимодействовать с.
- Настройка DialogResult на true закроет диалог, который может быть проверен для вызывающего родителя.
- Настройка DialogResult на false будет также закройте диалог, и в этом случае вы пропустите обновление значений в вызывающее окно.
- Нажатие кнопки X в окне автоматически устанавливается DialogResult to false
- Вы можете иметь общедоступные свойства в диалоговом окне, которые можно установить перед выполнением ShowDialog, и получить значения после исчезновения диалога. Он будет доступен, пока диалог по-прежнему находится в области видимости.