كيف يمكنني إغلاق نموذج عندما ينقر المستخدم خارج نافذة النموذج؟

StackOverflow https://stackoverflow.com/questions/298491

  •  08-07-2019
  •  | 
  •  

سؤال

وأريد أن إغلاق System.Windows.Forms.Form إذا كان المستخدم بالنقر فوق أي مكان خارجها. لقد حاولت استخدام IMessageFilter، ولكن يتم تمرير حتى ذلك الحين أي من الرسائل إلى PreFilterMessage. كيف يمكنني الحصول على نقرات خارج نافذة للنموذج؟

هل كانت مفيدة؟

المحلول 2

ف بابا في <لأ href = "https://stackoverflow.com/questions / 298626 / ما دو لهذه-wndproc رموز-يعني "> هذا السؤال، لقد وجدت هذا الحل الذي يتيح لي الفرصة لاستخدام 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);
}

نصائح أخرى

في حالة إلغاء تنشيط النموذج الخاص بك، ووضع "this.Close ()". سوف النموذج الخاص بك يغلق بمجرد النقر فوق أي مكان آخر في ويندوز.

تحديث: أعتقد أن ما لديك الآن هو زر الحجم، وداخل الحدث Click إنشاء مثيل من حيث الشكل VolumeSlider الخاص بك وجعلها تظهر من خلال الدعوة ShowDialog () الذي يمنع حتى يغلق المستخدم شكل برزت المتابعة . في السطر التالي تقرأ حجم المستخدم اختيار واستخدامها في البرنامج.

وهذا على ما يرام، ولكن كما كنت قد لاحظت أنه يفرض على المستخدم إغلاق صراحة المنبثقة من أجل الحصول على العودة إلى البرنامج الرئيسي. عرض () هو الأسلوب كنت تريد حقا أن استخدام هنا على شكل النوافذ المنبثقة، ولكن مشاهدة () لا يمنع مما يعني أن الحدث Click مرة أخرى على شكل التشطيبات الرئيسية الخاصة بك دون معرفة ما يفترض أن تكون وحدة التخزين الجديدة.

وهناك حل بسيط هو خلق أسلوب عام في النموذج الرئيسي من هذا القبيل:

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

وبعد ذلك، في الحدث انقر على زر حجم الخاص بك (كما في النموذج الرئيسي)، وجعل لكم 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);

وبعد ذلك في حالة إلغاء تنشيط شكل VolumeSlider من شأنه أن كنت وضعت this.Close () على النحو المذكور أعلاه. سوف النموذج الخاص بك ثم تتصرف كما هو متوقع.

ومع حل سيمون كان لي نفس المشكلة describt نعوم. مع التعليمات البرمجية التالية لقد تجنب "من خلال النقر" مشكلة ...

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();
        }
    }
}

إذا كان هو شكل الطفل في تطبيق MDI، هل يمكن أن اعتراض انقر في النموذج الأصل، وإلا فإن الحل سيكون الفوضى.

وأنا لست مقتنعا ما يوحي لك يمثل السلوك اجهة بديهية على أي حال. هل أنت متأكد من أن هو أفضل تصميم؟

إذا كنت تحاول أن تجعل نافذة منبثقة أن يتصرف قليلا مثل قائمة، إلا أنه يتيح لك التفاعل مع عناصر التحكم الخاصة بك، قد تتمكن من محاولة استضافة على UserControl داخل القائمة المنسدلة toolstrip.

وببساطة WAY: على 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

وهذا هو بسيط:

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();
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top