Как закрыть форму, когда пользователь щелкает за пределами окна формы? - PullRequest
5 голосов
/ 18 ноября 2008

Я хочу закрыть System.Windows.Forms.Form, если пользователь щелкнет где-нибудь за ее пределами. Я пытался использовать IMessageFilter, но даже тогда ни одно из сообщений не было передано в PreFilterMessage. Как получать клики за пределами окна формы?

Ответы [ 7 ]

7 голосов
/ 18 ноября 2008

В событии Deactivate вашей формы поставьте «this.Close ()». Ваша форма закроется, как только вы нажмете где-нибудь еще в Windows.

Обновление: я думаю, что у вас есть кнопка громкости, и внутри события Click вы создаете экземпляр формы VolumeSlider и отображаете его, вызывая ShowDialog (), который блокируется, пока пользователь не закроет всплывающую форму. , В следующей строке вы читаете том, выбранный пользователем, и используете его в своей программе.

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

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

public void SetVolume(int volume)
{
    // do something with the volume - whatever you did before with it
}

Затем в событии Click вашей кнопки громкости (также в главной форме) вы заставляете VolumeSlider выглядеть так:

VolumeSlider slider = new VolumeSlider();
slider.Show(this); // the "this" is needed for the next step

В форме VolumeSlider, когда пользователь работает (я думаю) с полосой прокрутки, вы помещаете этот код в событие ValueChanged на полосе прокрутки (я думаю, что это так):

MainForm owner = (MainForm)this.Owner;
owner.SetVolume(scrollbar.Value);

А затем в событие Deactivate формы VolumeSlider вы должны поместить this.Close (), как указано выше. Ваша форма будет вести себя как положено.

5 голосов
/ 19 ноября 2008

Благодаря p-daddy в этом вопросе я нашел решение, позволяющее мне использовать ShowDialog:

protected override void OnShown(EventArgs e)
{
    base.OnShown(e);
    this.Capture = true;
}

protected override void OnCaptureChanged(EventArgs e)
{
    if (!this.Capture)
    {
        if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position))
        {
            this.Close();
        }
        else
        {
            this.Capture = true;
        }
    }

    base.OnCaptureChanged(e);
}
4 голосов
/ 31 июля 2012

С решением Саймона у меня была та же проблема, описанная Ноамом. С помощью следующего кода я избежал проблемы "Click through" ...

protected override void WndProc(ref Message m)
{    
    base.WndProc(ref m);

    // if click outside dialog -> Close Dlg
    if (m.Msg == NativeConstants.WM_NCACTIVATE) //0x86
    {
        if (this.Visible)
        {
            if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position))
                this.Close();
        }
    }
}
0 голосов
/ 17 марта 2017

это просто:

private void button1_Click(object sender, EventArgs e)
    {
        Form f = new Form();
        f.LostFocus +=new EventHandler(f_LostFocus);
        f.Show();
    }

    void f_LostFocus(object sender, EventArgs e)
    {
        Form f = sender as Form;
        f.Close();
        f.Dispose();
    }
0 голосов
/ 16 декабря 2016

ПРОСТОЙ ПУТЬ: в Form1 используйте этот код для вызова form2:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles     Button1.Click
    Form2.Owner = Me
    Form2.Show()
End Sub

и затем используйте этот код в форме form1:

Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
    If Form2.IsHandleCreated = True Then
        Form2.Close()
    End If
End Sub
0 голосов
/ 18 ноября 2008

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

0 голосов
/ 18 ноября 2008

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

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

...