Вопрос

Я пишу приложение (С# + wpf), в котором все диалоги модального стиля реализованы как UserControl поверх полупрозрачной сетки, закрывающей основную Window.Это означает, что существует только один Window и он поддерживает внешний вид всех приложений фирмы.

Чтобы показать MessageBox, синтаксис следующий:

CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
   // the rest of the function
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b); 

Как видите, поток выполнения не только фактически инвертирован, но и ужасно многословен по сравнению с классической версией .NET:

MessageBox.Show("hello world");
// the rest of the function

Что я действительно ищу, так это способ не возвращаться из base.ShowMessageBox до тех пор, пока им не будет вызвано событие закрытия диалога, но я не понимаю, как можно дождаться этого, не зависая поток графического интерфейса и, таким образом, не позволяя пользователю когда-либо нажимать ОК.Я знаю, что могу использовать функцию делегата в качестве параметра для ShowMessageBox функция, которая как бы предотвращает инверсию выполнения, но все же вызывает какой-то сумасшедший синтаксис/отступы.

Я упускаю что-то очевидное или есть стандартный способ сделать это?

Это было полезно?

Решение

Возможно, вы захотите взглянуть на этот статья о CodeProject и этот статья на MSDN.В первой статье рассказывается, как вручную создать блокирующее модальное диалоговое окно, а во второй статье показано, как создавать собственные диалоговые окна.

Другие советы

Способ сделать это — использовать ДиспетчерКадр объект.

var frame = new DispatcherFrame();
CustomMessageBox b = new CustomMessageBox("hello world");
c.DialogClosed += ()=>
{
    frame.Continue = false; // stops the frame
}
// this raises an event listened for by the main window view model,
// displaying the message box and greying out the rest of the program.
base.ShowMessageBox(b);

// This will "block" execution of the current dispatcher frame
// and run our frame until the dialog is closed.
Dispatcher.PushFrame(frame);

Вы можете превратить свою функцию в итератор, который возвращает IEnumerator<CustomMessageBox>, то напишите это так:

//some code
yield return new CustomMessageBox("hello world");
//some more code

Затем вы должны написать функцию-оболочку, которая принимает перечислитель и вызывает MoveNext (который будет выполнять всю функцию до следующего yield return) в DialogClosed обработчики.

Обратите внимание, что функция-обертка не будет блокирующим вызовом.

Настройте еще один цикл сообщений в классе окна сообщений.Что-то вроде :

public DialogResult ShowModal()
{
  this.Show();

  while (!this.isDisposed)
  {
    Application.DoEvents();
  } 

   return dialogResult;
}

Если вы посмотрите на Windows.Form в Reflector, вы увидите, что он делает что-то вроде этого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top