Как заставить кнопки, TextBoxes перерисовать на форме после закрытия MessageBox в C#

У меня есть форма с кнопками, текстовыми полями и пользовательскими элементами управления на нем. Когда кнопка нажата, она вызывает метод в другом классе. В этом классе открывается окно сообщения. Когда пользователь нажимает кнопку "ОК", messageBox закрывается, и метод класса продолжается примерно 10 секунд, прежде чем завершиться. В течение этих 10 секунд любой текстовый блок или кнопка, на которой окно сообщения было закрыто, все еще отображает блок сообщений (они не перекрашиваются).

Вопрос в том, как заставить все перекрасить в форме. Проблема в том, что класс messageBox не знает формы, вызвавшей его.

Фрэнк

5 ответов

Вы можете попробовать с

Application.DoEvents()

сразу после закрытия окна сообщения. Однако - если вы не выполните метод, который вы вызываете в этом другом классе в фоновом потоке, - ваш пользовательский интерфейс не будет реагировать в течение 10 секунд.

Это 10 секунд, потраченные на работу полностью в пользовательском интерфейсе? Если нет, то это должно быть сделано в отдельном потоке. Даже если вы обновите саму форму, вы по-прежнему будете иметь не отвечающий пользовательский интерфейс в течение 10 секунд, что не идеально.

См. Мое руководство по созданию потоков, где приведен пример выполнения кода в другом потоке и обратного вызова в потоке пользовательского интерфейса. Имейте в виду, что это "старый" способ действий - BackgroundWorker упрощает работу.

Проблема здесь в том, что у вас есть обработка, которая происходит в потоке пользовательского интерфейса и блокирует сообщение рисования. Вызов Refresh или Invalidate не исправит это, поскольку вы все еще блокируете поток, который будет выполнять эти операции.

Скорее вы должны взять эту обработку и переместить ее в другой поток, а затем обновить ваш поток пользовательского интерфейса (соответственно, с помощью метода Invoke, скорее всего, чем нет), когда вы выполняете работу в фоновом потоке.

Чтобы заставить все перерисоваться, вы можете вызвать Invalidate() в главной форме.

Ваша проблема в том, что вы делаете свою работу в потоке пользовательского интерфейса. Пользовательский интерфейс не будет перекрашен, пока ваш метод не вернется, что позволит продолжить цикл обработки сообщений Windows.

Решение состоит в том, чтобы запустить ваш метод работы в другом потоке. Возможно, класс BackgroundWorker хорошо решит вашу проблему.

Изменить: см. Эту статью для подробного объяснения:
http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

Другие вопросы по тегам