2016-08-03 2 views
0

У меня есть winform со следующим кодом, который открывает внешнюю программу при открытии формы. Если программа закрывается, появляется диалоговое окно с возможностью возврата, чтобы нажать кнопку. Это закроет диалоговое окно и вернется к исходной форме, а затем запустит эту функцию, чтобы снова открыть внешнюю программу.ShowDialog() не препятствует клику на исходной форме

В этом случае исходная форма STILL clickable И функция не работает. Есть идеи?

public Manager() 
    { 
     InitializeComponent(); 
     ExternalProgramOpen(); 

    } 

    private void ExternalProgramOpen() 
    { 
     Process startProgram = Process.Start("program.exe", Program.ConnectionArg); 
     startProgram.EnableRaisingEvents = true; 
     startProgram.Exited += this.PrematureClose; 
    } 

    private void PrematureClose(object sender, EventArgs e) 
    { 
     ManagerWarning messagepopup = new ManagerWarning(); 
     messagepopup.ShowDialog(); 
     using (var ManagerWarning = new ManagerWarning()) 
     { 
      if (ManagerWarning.ShowDialog() == DialogResult.Retry) 
      { 
       ExternalProgramOpen(); 
      } 
     } 
    } 
+0

Никогда не отображать пользовательский интерфейс на рабочем потоке, много неприятных проблем с этим за Диалоги не является модальным. Простым обходным путем является добавление 'startProgram.SynchronizingObject = this;' –

+1

Я даже не уверен, что ваш 'PrematureMethod' должен даже компилироваться. Вы уверены, что код, который вы опубликовали, является тем, который вы используете? Вы создаете и показываете два последовательных модальных диалога, один за пределами оператора 'using', а другой внутри, используя имя класса в качестве имени экземпляра ... вы делаете что-то явно неправильно. – InBetween

+0

Он скомпилирован просто отлично. Теперь с добавлением кода 'invoke' он делает то, что он должен делать (за исключением части с нажатием кнопки диалогового окна). –

ответ

2

Причиной этого эффекта, вероятно, что Exited событие не вызывается в том же потоке пользовательского интерфейса, который начался процесс.

Когда вы вызываете ShowDialog() из другого потока, новое окно не будет использовать и блокировать исходный поток пользовательского интерфейса.

Чтобы решить эту проблему, проверьте InvokeRequired является true и использовать Invoke:

private void PrematureClose(object sender, EventArgs e) 
{ 
    if (InvokeRequired) 
    { 
     Invoke(new Action(() => PrematureClose(sender, e))); 
     return; 
    } 

    // your code here 
    // ... 
} 
+0

Хорошо спасибо, тестируя это сейчас. –

+0

Форма не только не в том же потоке, она даже не в том же процессе * – Servy

+0

@Servy могу я неправильно понять вопрос OP, но для меня кажется, что уже закончился другой процесс, и он открывает новую форму в своем оригинале обработать. Таким образом, формы, о которых он говорит, похоже, находятся в одном и том же оригинальном процессе, а не выходе. –

Смежные вопросы