سؤال

هل من الممكن ترك contextMenuStrip مفتوحًا بعد تحديد/فحص عناصر معينة؟

أخطط لاستخدام contextMenuStrip بسيط لتعيين عامل تصفية (بهذه الطريقة يمكنني استخدام نفس المرشح إما في القائمة أو كخيار النقر بزر الماوس الأيمن).

تسرد القائمة عددًا من العناصر، وأود أن يتمكن المستخدم من تحديد العناصر باستخدام وظيفة التحقق الأساسية.بمجرد الانتهاء من التحديد، يمكن للمستخدم النقر فوق خيار تنشيط عامل التصفية أو يمكنه النقر خارج القائمة لتنشيط عامل التصفية أو إلغائه.

في حدث التحديد/النقر، يتم إغلاق القائمة عادةً.هل من الممكن إبقاء القائمة مفتوحة عند حدث النقر؟

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

المحلول

لمنع contextmenu من إغلاق عند النقر فوق عنصر، قم بما يلي.

في الحدث mousedown من ContextMenuItems تعيين علامة إلى false ثم تعيين إعادته إلى true في الحدث الختامي للcontextmenu.

مثال:

Private blnClose As Boolean = True

Private Sub MoveUpToolStripMenuItem_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MoveUpToolStripMenuItem.MouseDown

     blnClose = False

End Sub

Private Sub ContextMenuStrip1_Closing(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripDropDownClosingEventArgs) Handles ContextMenuStrip1.Closing

     e.Cancel = Not blnClose
     blnClose = True

End Sub

نصائح أخرى

في حالة المبرمجين في المستقبل ويتساءل كيفية القيام بذلك، وهذا هو ما كنت أحسب. هذا وسوف يتم إغلاق قائمة السياق إذا تم النقر أي بند. إنشاء الحدث قائمة السياق الشريط الختامية وإعداد بيان إذا لإلغاء الحدث وثيق إذا تم itemclicked السبب قريبة.

private void contextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
        e.Cancel = true;
}

والحدث الإنتهاء

ووضع e.Cancel = فيا لترك القائمة مفتوحة

والمشكلة فقط هي الحدث لا اقول لكم ما تم النقر، ولذلك عليك أن تتبع هذا بنفسك. تعيين بعض نوع من العلم في الحدث Click من العناصر التي تريد أن تبقي على القائمة مفتوحة. ثم في حال الإنتهاء تحقق العلم ووضع e.Cancel بشكل مناسب.

وأنا لا أعتقد أن هناك خاصية لهذا في ContextMenuStrip.

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

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

وOnClosing، تأليف: e.Cancel = = e.CloseReason ToolStripDropDownCloseReason.CloseCalled. ثم عندما تقرر إغلاق، والدعوة إغلاق ().

وهذه هي طريقتي. انها خالية من وميض و- أعتقد - قليلا أكثر مرونة

إذا كان لديك مجموعة من ToolStripMenuItems كنت ترغب في استخدام أزرار تبديل (خيار تشغيل / إيقاف) كما حاول هذا:

ctxWildCards هو مجرد بلدي ContextMenuStrip، وتستخدم لتحديد المرشحات على أساس أنواع الملفات - للبحث أو FileDialogs)

وهذا هو في Visual Basic (من الواضح،!)، حتى تتمكن من إضافة معالجات برمجيا أو باستخدام 'مقابض ...' بنود

.
  Private Sub OnOffToolStripMenuItem_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) 

    Dim t = TryCast(sender, ToolStripMenuItem)
    If Not t Is Nothing Then
        'Since you may have more On/off-Items, check to see if the Owner is the ContextMenuStrip 
        If t.Owner Is ctxWildCards Then
           ' The ContextMenuStrip will stay open on Right-click, i.e. the user can check and close by clicking 'normally'
            ctxWildCards.AutoClose = (e.Button = Windows.Forms.MouseButtons.Left)
        End If
        'Just me using a custom image for checked items.
        t.Checked = Not t.Checked
        t.Image = If(t.Checked, rdoImage, Nothing)
    End If
  End Sub

 ' On leaving ToolStripMenuItems of the ContextMenuStrip, allow it to AutoClose
  Private Sub OnOffToolStripMenuItem_MouseLeave(sender As System.Object, e As System.EventArgs)
  ctxWildCards.AutoClose = True
End Sub

ما وجدته غريبًا هو ذلك ContextMenuStrip.Closing حرائق الأحداث قبل ال ToolStripMenuItem.Click حدث.وكان الحل هو الاستخدام ContextMenuStrip.ItemClicked الحدث حيث لديك e.ClickedItem, ، ثم تحقق مما إذا كان أحد العناصر التي لن يتم إغلاقها عند النقر عليها ContextMenuStrip, ، وقم بتعيين العلامة المناسبة.ثم في ContextMenuStrip.Closing يمكنك ضبط e.Cancel = true; إذا تم تعيين العلم أيضا.لا تنس إعادة ضبط العلم بالرغم من ذلك.

bool isRunAtStartupClicked;
private void ContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{   
    if (e.ClickedItem == trayIcon.ContextMenuStrip.Items["miRunAtStartup"])
    {   
        isRunAtStartupClicked = true;
    }
}

private void ContextMenuStrip_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{   
    if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
    {   
        if (isRunAtStartupClicked)
        {   
            isRunAtStartupClicked = false;
            e.Cancel = true;
        }
    }
}

وأفضل طريقة لقد وجدت للقيام بذلك دون الخفقان هو استخدام الأحداث MouseDown وMouseLeave عن كل زر في القائمة المنسدلة.

مثال:

Private Sub ToolStripMenuItem2_Mousedown(sender As Object, e As EventArgs) Handles ToolStripMenuItem2.MouseDown
        ΥπηρεσίεςToolStripMenuItem.DropDown.AutoClose = False
End Sub

Private Sub ToolStripMenuItem2_MouseLeave(sender As Object, e As EventArgs) Handles ToolStripMenuItem2.MouseLeave
        ΥπηρεσίεςToolStripMenuItem.DropDown.AutoClose = True
End Sub

ولقد وجدت هذا مفيدا لأغراض بلدي.

Private Sub CM_Closing(sender As Object, e As ToolStripDropDownClosingEventArgs) Handles CM.Closing
    If e.CloseReason = ToolStripDropDownCloseReason.ItemClicked Then
        Dim ItemClicked As String = CM.GetItemAt(New Point(Cursor.Position.X - CM.Left, Cursor.Position.Y - CM.Top)).Name
        If ItemClicked = "CMHeader" Then
            e.Cancel = True
        End If
    End If
End Sub

هل يمكن استخدام ItemClicked لقراءة البطاقات أو بعض الممتلكات الأخرى.

وأردت فقط عنصر بسيط هو أن أوضح للمستخدم الذي البند قائمة السياق كان على وشك تأثير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top