Я хочу показать диалоговое окно как модальное (т. Е. Блокирует все взаимодействия со всеми другими пользовательскими интерфейсами в моем приложении), но я не хочу, чтобы этот вызов блокировал выполнение, как мне это сделать?

Это некрасиво, но по независящим от меня причинам у нас есть только один поток, и мы не можем создать больше. в настоящее время, когда мы делаем трудоемкий прогресс, мы хотим показать индикатор выполнения, но для того, чтобы он обновлялся во время выполнения процесса, мы должны вызвать DoEvents () (eek).

Неудивительно, что иногда это вызывает несколько проблем, но если бы мы могли легко отключить весь пользовательский интерфейс, кроме индикатора выполнения, это могло бы помочь.

Я получил эту идею, прочитав этот ответ здесь: https://stackoverflow.com/a/5183623/259846

Изменить: модальный диалог - это просто тот, который отключает все остальные пользовательские интерфейсы - можно взаимодействовать только с модальным диалоговым окном. Это не зависит от того, блокирует ли операция по отображению этого диалогового окна. Я не вижу причин, по которым вы не могли бы теоретически иметь функцию, которая показывает модальное диалоговое окно без блокировки, пока окно не будет закрыто.

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

И да, у меня может быть только один поток, без параллелизма.

0
matt 21 Окт 2019 в 09:29
Выполнить выполнение в другом потоке.
 – 
Michał Turczyn
21 Окт 2019 в 09:30
Непонятно, о чем вы спрашиваете. если вы не хотите блокировать, используйте ShowDialog, если вы не хотите использовать DoEvents, используйте шаблон async и await
 – 
Michael Randall
21 Окт 2019 в 09:33
Нет блокирующего модального диалога в одном потоке? Ваш диалог либо модальный, либо неблокирующий. И то, и другое невозможно.
 – 
HimBromBeere
21 Окт 2019 в 09:36
Является ли одиночный поток жестким ограничением? Я имею в виду, что даже BackgroundWorker - это не вариант, верно?
 – 
Stas Ivanov
21 Окт 2019 в 09:40
@HimBromBeere, ShowDialog - это способ показать модальный диалог и блоки ... Как мне использовать async и await для отображения модального диалога?
 – 
matt
21 Окт 2019 в 10:02

2 ответа

Отключите все остальные элементы вручную при открытии DialogBox. Затем включите их при закрытии коробки.

Например: Button.Enabled = false;

Проверьте это, чтобы отключить все элементы управления Как отключить все элементы управления в форме кроме кнопки?

Вы также можете поставить прозрачный прямоугольник перед всем, что вы не можете щелкнуть. Затем скройте его, когда диалоговое окно закроется.

1
Bjorn 21 Окт 2019 в 10:50
1
Я очень надеюсь, что это не лучший ответ, но он правильный.
 – 
matt
21 Окт 2019 в 10:01
Вы можете выполнять рекурсивную блокировку всех элементов в WinForms. Проверьте это: stackoverflow.com/questions/13446129/…
 – 
Bjorn
21 Окт 2019 в 10:44

Я придумал один способ сделать это. Мой вопрос, вероятно, явно не указывает на мой вариант использования, это решение по-прежнему использует блокирующий вызов для создания модального диалогового окна, но по-прежнему позволяет мне выполнять цикл «выполняйте работу, обновляйте прогресс» с открытым диалоговым окном.

var progress = new Form();
this.BeginInvoke(new Action(() =>
{
    for (int i = 0; i < 100; i++)
    {
        System.Threading.Thread.Sleep(16); // do a bit of my process
        // Update progress dialog
        Application.DoEvents();
    }
    progress.Close();
}));
progress.ShowDialog();
0
matt 21 Окт 2019 в 10:45
Что, если ваш процесс занимает больше 1600 миллисекунд?
 – 
HardCode
22 Окт 2019 в 22:57