У меня проблема с закрытием диалога, но он отображается только во второй раз, и только при закрытии определенным образом.
В диалоговом окне есть единственная кнопка, которая объявлена как кнопка отмены, т. е. имеет значение IsCancel="True". Нет обработчика события нажатия кнопки. Я могу показать этот диалог и закрыть его каждый раз, либо нажав кнопку, либо нажав клавишу Escape, и с этим нет проблем, он работает каждый раз.
У меня также есть концепция сеанса пользователя. Если сеанс пользователя истекает, все открытые диалоги должны автоматически закрываться. Это отлично работает, когда срок действия сеанса истекает, когда диалоговое окно отображается в первый раз, но если диалоговое окно уже было показано один раз и либо было закрыто путем явного нажатия кнопки, либо до истечения срока действия сеанса, то по истечении срока действия следующего сеанса пока отображается диалоговое окно, я получаю исключение «DialogResult может быть установлено только после того, как окно будет создано и показано как диалоговое окно».
Это очень любопытно, так как я могу посмотреть DialogResult диалогового окна до истечения срока действия второго сеанса, и он равен нулю. Когда я устанавливаю точку останова в момент истечения срока действия сеанса и собираюсь установить DialogResult, для DialogResult уже устанавливается значение false. Я понятия не имею, как это становится ложным.
Я использую Unity и задаюсь вопросом, дает ли он мне один и тот же экземпляр диалога каждый раз. Но если бы это было так, разве DialogResult не стал бы ложным, как только я разрешил ссылку на диалог? Это не так, это нуль, как я и ожидал.
Я просмотрел это, это, это и this, но ни один из них не помогает.
Здесь я получаю ссылку и показываю диалог
public void ShowLoginBarcode(string username) {
BarcodeLoginForm frm = _Unity.Resolve<BarcodeLoginForm>();
frm.Owner = Application.Current.MainWindow;
BarcodeLoginVM vm = frm.ViewModel;
vm.Username = username;
frm.ShowDialog();
}
Вот xaml.cs для диалога
public partial class BarcodeLoginForm : Window, ICloseableDialog {
public void CloseDialog(bool dialogResult) {
DialogResult = dialogResult;
}
private void Window_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) {
// register the view with the view model, so the view model can call the view's CloseDialog method
if (e.OldValue != null)
((BarcodeLoginVM)e.OldValue).SetView(null);
if (e.NewValue != null)
((BarcodeLoginVM)e.NewValue).SetView(this);
}
}
Вот часть модели представления.
public void SetView(ICloseableDialog view) {
_Dialog = view;
}
private void Session_OnTimeoutChange(object sender, EventArgs e) {
if (_Session.HasExpired)
CloseDialog(false);
}
private void CloseDialog(bool dialogResult) {
_Dialog?.CloseDialog(dialogResult);
}
Вот простейший набор шагов, которые показывают проблему:
- покажи диалог.
- нажмите кнопку закрытия, чтобы закрыть диалоговое окно. (В качестве альтернативы можно позволить сеансу истечь, чтобы он закрыл диалоговое окно.)
- показать диалог снова. (Если я смотрю на DialogResult, пока диалоговое окно видимо, оно равно null. Я добавил обработчик событий KeyPreview, чтобы поставить на него точку останова.)
- позволить сеансу истечь. В момент, когда DialogResult = dialogResult собирается выполниться в методе CloseDialog диалогового окна, для DialogResult уже установлено значение false.
Итак, есть идеи?
Изменить: я могу обойти проблему, изменив метод xaml.cs CloseDialog, чтобы проверить, что DialogResult имеет значение null, прежде чем присваивать значение, но я не понимаю, зачем это нужно. Как можно установить DialogResult перед выполнением этого кода?
public void CloseDialog(bool dialogResult) {
if (!DialogResult.HasValue)
DialogResult = dialogResult;
}