2009-05-03 4 views
34

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

Не могли бы вы объяснить, в какой ситуации я мог бы получить описанную проблему?

UPDATE:

Ну, я сделал много экспериментов, и я не мог получить никаких реальных неожиданных проблем с использованием ShowDialog() (без указания владельца).

Так что я думаю, что это просто слухи, что ShowDialog() может привести к проблемам. Если вы не согласны - дайте мне образец кода, пожалуйста, что приводит к проблеме.

+4

Это не похоже на применение в winforms, но для записи я пришел сюда, потому что у меня были проблемы с WPF. Если бы я переключился на другое приложение, когда я снова нажал на родительскую форму, дочерний диалог застрял позади (облом, когда дочерний диалог был установлен, чтобы не отображаться на панели задач). Настройка владельца диалогового окна устранена. – Benjol

+4

Запустите фоновый рабочий и вызовите ShowDialog.Окно не будет отображаться перед вашим приложением, а на фоне (просто чтобы раздражать нас программисты, это случается только время от времени). – CodingBarfield

+0

Barfieldmv, я попытался сделать то, что вы предложили, и форма появится сверху, а не на заднем плане. – nightcoder

ответ

6

Просто, чтобы лучше понять отношения владельца собственности:

.NET позволяет форму на «собственные» и другие формы. Собственные формы полезны для плавающих панелей инструментов и окон команд . Одним из примеров принадлежащей форме является окно «Найти и заменить» в Microsoft Word. Когда окно владельца сведено к минимуму, собственные формы также автоматически сводятся к минимуму. Когда форма собственности перекрывает владельца, она всегда отображается сверху.

(c) «Профили .NET 2.0 Windows Forms и пользовательские элементы управления» Мэтью Макдональда.


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

Одной из особенностей этих отношений является то, что принадлежит форме влияет на поведении своего владельца формы (при использовании ShowDialog):

  • Форма владельца не может быть сведена к минимуму, развернута, или даже переехала.
  • Собственная форма блокирует ввод мыши и клавиатуры в форму владельца.
  • Форма владельца сводится к минимуму при наличии соответствующей формы.
  • Только принадлежащая ему форма может быть закрыта.
  • Если и владелец, и принадлежащие ему формы сведены к минимуму, и если пользователь нажимает Alt + Tab для переключения в принадлежащую ему форму, активная форма активируется.

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

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

Хотя ShowDialog устанавливает неявный владелец собственности отношения, нет встроенного способа для принадлежащей формы перезвонить или запрос форму, открытых его. В случае неспособности вы можете установить новое свойство владельца , чтобы установить отношения владельца. В качестве ярлыка вы можете передать форму владельца в качестве аргумента для перегрузки метода Show, который также принимает параметр IWin32Window (IWin32Window реализован объектами пользовательского интерфейса Windows Forms, которые открывают свойство Win32 HWND через IWin32Window. Обработать свойство).

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

(c) «Программирование Windows Forms 2.0» Криса Продажса, Майкла Вайнхардта.

+0

Life saver, теперь я могу делать то, что мне нужно – Takarii

+0

Замечательный подробный ответ! –

5

Необязательный ShowDialog() просто использует родительский элемент по умолчанию. Для чего это стоит, родитель по умолчанию - это любое «активное окно». Когда вы заботитесь о родителях, вам нужно установить его явно.

+0

Спасибо, но я знаю, что ShowDialog() использует текущее активное окно, я просто не знаю, как может возникнуть ситуация, когда диалог появится так, как пользователь не сможет его увидеть. – nightcoder

7

«Текущее активное окно» обычно относится к окну переднего плана, но только если оно принадлежит текущему потоку - см. GetActiveWindow в MSDN.

(Актуальная информация содержится в содержимом сообщества, но комментатор прав, если нет активного окна "per-thread", AFAIK).

Итак, когда пользователь переключился на другое окно приложений (или потоков), вы получите некоторое «окно по умолчанию». Даже если .NET делает какую-то магию здесь, модальность будет нарушена: целевое родительское окно не отключается (например, вы можете переключиться на свое главное окно, закрыть его или изменить что-то, что часто нарушает ваше приложение из-за повторной установки) ,

Кроме того, если другое приложение в настоящее время активно, ваше диалоговое окно не будет отображаться сверху, но оно будет скрыто за другим окном.

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

Практически это случается редко: если вы откроете диалоговое окно в ответ на меню или нажмите кнопку в главном окне, пользователю практически не удастся переключиться в другое окно.

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

+5

Как правило, если можно указать родителя, необходимо указать родителя. Это никогда не болит, и это часто помогает. –

+0

У меня на самом деле проблема: я запускаю внешний процесс из плагина outlook, и он не отображает диалоговое окно. Любые идеи, как показать диалог? У него нет формы -> я просто хочу показать диалог. Если раньше я называю «MessageBox.Show» - он работает - иначе нет. – bernhardrusch

+0

@bernhardrusch: Вы пробовали указать .NET-эквивалент GetDesktopWindow как родителя? – peterchen

20

Один раздражения я нашел с ShowDialog() Vs ShowDialog (это).

Запустите TestApp, покажите newform.ShowDialog(), нажмите «показать рабочий стол» на панели задач или панели быстрого запуска, нажмите TestApp на панели задач. Он показывает Mainform. Вы должны сделать Alt-Tab, чтобы перейти к вашей новой форме.

VS

Запустить TestApp, показать newform.ShowDialog (это), нажмите кнопку «Показать рабочий стол» на панели задач или панели быстрого запуска, нажмите на TestApp на панели задач. Он показывает новую форму сверху.

+0

У меня есть точная проблема, которую вы описываете. Но я изменил ShowDialog() на ShowDialog (это), и это не помогло. – Colin

1

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

1

Рассмотрим следующий пример:

В главной форме, то есть ListView, с поддержкой редактирования этикетки. Когда отредактирована конкретная метка, вы запустите второе окно (используя ShowDialog() в AfterLabelEdit). Новая форма не отображается в панели задач.

Если ваш пользователь начинает редактировать метку, затем нажимает на другое приложение, после чего отображает вторая форма, но при возврате в приложение пользователь будет представлен только вашей основной формой, отключенной, так как показывается модальное диалоговое окно. Тем не менее, обычный мигающий механизм (который привносит модальный диалог в шрифт, если вы нажмете на вызывающего) не будет работать (конечно, потому что вызов AfterEdit еще не вернулся), и ваш пользователь не сможет достичь второй формы, кроме как на велосипеде через открытые окна с помощью Ctrl + Tab.

Вызов ShowDialog(this) устраняет эту проблему.

0

У меня была эта проблема, и для ее решения изменилось свойство состояния Windows в нормальное состояние, потому что, возможно, оно сводилось к минимуму.

0

Я только что нашел случай, когда не указано, что владелец, использующий this, вызвал серьезную проблему.

После запуска мое приложение заставляет себя работать в полноэкранном режиме, а также всегда имеет фокус, даже если пользователь пытается выполнить Alt + Tab, если только вы не входите в систему как администратор или разработчик.

Когда я использую ShowDialog() на пользовательской форме, появится диалоговое окно за мое приложение для какой-то причины, а само приложение перестает отвечать на запросы, потому что диалоговое окно в данный момент. Если я использую ShowDialog(this), тогда форма отображается так, как предполагалось.

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