По причинам, которые я считаю здесь неактуальными, у меня есть один или несколько потоков, которые взаимодействуют с одним экземпляром пользовательского интерфейса (формы).
В рабочих потоках мне нужно сообщать о прогрессе или вводить данные или простые варианты. Все они происходят от взаимодействия пользователя с пользовательским интерфейсом и, конечно же, для M $ .NET все пользовательские интерфейсы выполняются в основном потоке.
Очевидно, что мне нужно обрабатывать синхронизацию потоков между потоками пользовательского интерфейса (основным) и рабочими. Я делаю это, правильно проверяя InvokeRequired
и компанию.
Существует множество постов и статей, в которых обсуждаются несоответствия и тонкости в InvokeRequired
, IsHandleCreated
, IsDisposed
и т. Д., Поэтому я не буду об этом говорить.
Я просто должен сказать, что мой пользовательский интерфейс, который является просто формой, должен был отображаться как модальная или немодальная форма, в зависимости от желания вызывающего абонента.
Один мог просто UI.Warn( "Warning!" )
, а другой мог UI.Question( "Make a choice:", options... )
.
Теперь рассмотрим следующий отрывок из документации M $ DN:
Form.ShowDialog Метод:
В отличие от немодальных форм, метод Close не вызывается .NET Framework, когда пользователь нажимает кнопку закрытия формы ...
Я никогда не обращал внимания на то, что форма, показанная как модальная , тем не менее их разработчики говорят, что она не будет уничтожена, может упасть в неиспользуемое состояние после закрытия (скрытия).
Но это так!
Когда форма возвращается из ShowDialog( )
, ее Handle
просто отбрасывается, полагая, что когда она снова понадобится, будет вызван ShowDialog( )
и дескриптор будет воссоздан.
Я понятия не имею, почему M $ вещи нужны для этого, но я просто подумал, что смогу получить ту же самую форму, которая будет отлично работать, как модальный или немодальный без проблем. Документы M $ DN ничего не говорят о том, что это запрещено (или я слишком пьян, чтобы найти это)!
Ну, в конце концов, это относительно простой (и грязный) способ исправить это.
var r = ShowDialog( );
// Handle thrown away aftr "ShowDialog()" supposing the
// next one will recreate it.
if ( !this.IsHandleCreated )
{
// Force "Handle" recreation here, while in the main thread,
// before any "Show()" happens.
CreateHandle( );
}
return r;
Это работает, но мне интересно, не должно ли быть приличного способа достичь того же конца.
(Возможно, программирование в чем-то, что не несет в себе никакого предела совместимости с предками, как это делает .NET по-прежнему ...)