Как создать немодальную форму, кроме блокировки? - PullRequest
3 голосов
/ 20 декабря 2011

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

примерно так:

     void Foo()
     {
         CustomMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
         //block the code here, but user should be able to click on form, so that its equivalent to have clicked No;
         //if clicked No, return;

         //delete.
     }

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

Это выглядело бы так:

 void Foo()
 {
     NonModalMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
     //block thread till user clicks on form or messagebox buttons.
     //unblock when user clicks.
     //if No, return;

     //delete.
 }

Редактировать: я знаю, что это не стандартная практика, и я знаю, что немодальные формы не блокируют, в то время как модальные формы делают.Поэтому, пожалуйста, не рекомендуется довольствоваться поведением модальной или немодальной формы.Мой вопрос был бы, есть ли способ имитировать поведение ContextMenu с окнами форм.

Ответы [ 6 ]

3 голосов
/ 20 декабря 2011

Вы можете решить это довольно легко. Создайте и используйте модальное диалоговое окно, но переопределите WndProc этого диалогового окна и обработайте событие WM_MOUSEDOWN. Проверьте положение мыши вниз и, если оно находится над родительским окном, но не над самим диалогом, просто закройте диалоговое окно.

2 голосов
/ 20 декабря 2011

По сути, вы не можете легко сделать это в «блокирующем» вызове. То, что вы могли бы сделать достаточно легко, - это либо передать в форму информацию, необходимую для выполнения удаления, либо делегата для выполнения операции. Когда они нажимают Ok, вы просто выполняете операцию. Если они активируют родительскую форму, просто закройте дочернюю.

1 голос
/ 05 сентября 2012

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

[DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr hWnd, bool enable);

internal static DialogResult ShowDialogSpecial(this Form formToBeShown, Form parent)
{
    parent.BeginInvoke(new Action(() => EnableWindow(parent.Handle, true)));
    formToBeShown.ShowDialog(parent);

    return formToBeShown.DialogResult;
}

Просто вызовите метод расширения из любой родительской формы, например так:

var f = new Form();
f.ShowDialogSpecial(this);
//blocks but parent window will be active.

Конечно, вам нужно обрабатывать щелчки в родительской форме, чтобы закрыть дочернюю форму.

1 голос
/ 20 декабря 2011

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

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

Возможно, вместо этого вы могли бы обнаружить, что немодальное диалоговое окно теряет фокус, и автоматически закрыть его.Я вижу, что такое поведение имеет смысл для простого диалогового окна «Подтвердить удаление», но, как пользователь, моей первой реакцией будет спам клавишей ESC, чтобы закрыть диалоговое окно.

0 голосов
/ 22 февраля 2016

Более простой способ: установить для свойства TopMost формы значение True. Тогда это будет действовать как блокировка

0 голосов
/ 20 декабря 2011

Вы могли бы сделать что-то вроде:

public void ShowMe() {
    Show();
    while (!_receivedDeactivateEvent)
        Application.DoEvents();
}

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

...