निर्धारित करें कि ContextMenuStrip का उपयोग किस नियंत्रण पर किया गया था


84

मेरे पास ContextMenuStripकई अलग-अलग लिस्टबॉक्स में असाइन किया गया है। मैं यह पता लगाने की कोशिश कर रहा हूं कि जब ContextMenuStripयह क्लिक किया ListBoxगया था तो इसका क्या उपयोग किया गया था। मैंने शुरुआत के रूप में नीचे दिए गए कोड की कोशिश की, लेकिन यह काम नहीं कर रहा है। इसका senderसही मूल्य है, लेकिन जब मैं इसे असाइन करने का प्रयास करता हूं तो menuSubmittedयह अशक्त होता है।

private void MenuViewDetails_Click(object sender, EventArgs e)
{
    ContextMenu menuSubmitted = sender as ContextMenu;
    if (menuSubmitted != null)
    {
        Control sourceControl = menuSubmitted.SourceControl;
    }
}

कोई भी मदद बहुत अच्छी रहेगी। धन्यवाद।

नीचे दी गई सहायता का उपयोग करते हुए, मुझे लगा कि:

private void MenuViewDetails_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
            if (menuItem != null)
            {
                ContextMenuStrip calendarMenu = menuItem.Owner as ContextMenuStrip;

                if (calendarMenu != null)
                {
                    Control controlSelected = calendarMenu.SourceControl;
                }
            }
        }

समाधान के लिए धन्यवाद मैं देख रहा था। मुझे भी यही समस्या थी। लेकिन मेरा सुझाव है कि आप उन सभी ifकथनों का पालन न करें और if (menuItem == null) return;यदि आप मेरी तरह हैं और उनका उपयोग नहीं करना चाहते हैं, तो अपना कोड जो इसे संभालता है, उसे 2 अतिरिक्त स्तरों पर नेस्टेड किया जाएगा।
शॉन कोवैक

जवाबों:


123

एक के लिए ContextMenu:

समस्या यह है कि senderपैरामीटर संदर्भ मेनू पर आइटम को इंगित करता है जिसे क्लिक किया गया था, न कि संदर्भ मेनू।

हालांकि, यह एक साधारण फिक्स है, क्योंकि प्रत्येक MenuItemएक ऐसी GetContextMenuविधि को उजागर करता है जो आपको बताएगा ContextMenuकि उस मेनू आइटम में क्या है।

अपना कोड निम्नलिखित में बदलें:

private void MenuViewDetails_Click(object sender, EventArgs e)
{
    // Try to cast the sender to a MenuItem
    MenuItem menuItem = sender as MenuItem;
    if (menuItem != null)
    {
        // Retrieve the ContextMenu that contains this MenuItem
        ContextMenu menu = menuItem.GetContextMenu();

        // Get the control that is displaying this context menu
        Control sourceControl = menu.SourceControl;
    }
}

एक के लिए ContextMenuStrip:

यदि आप ContextMenuStripइसके बजाय का उपयोग करते हैं तो यह चीजों को थोड़ा बदल देता है ContextMenu। दो नियंत्रण एक दूसरे से संबंधित नहीं हैं, और एक का उदाहरण दूसरे के उदाहरण से नहीं डाला जा सकता है।

पहले की तरह, जिस आइटम पर क्लिक किया गया था, वह अभी भी senderपैरामीटर में वापस आ गया है , इसलिए आपको यह निर्धारित करना होगा ContextMenuStripकि यह व्यक्तिगत मेनू आइटम का मालिक है। आप Ownerसंपत्ति के साथ ऐसा करते हैं । अंत में, आप यह निर्धारित करने के लिए SourceControlसंपत्ति का उपयोग करेंगे कि कौन सा नियंत्रण संदर्भ मेनू प्रदर्शित कर रहा है।

अपना कोड इस तरह संशोधित करें:

private void MenuViewDetails_Click(object sender, EventArgs e)
{
     // Try to cast the sender to a ToolStripItem
     ToolStripItem menuItem = sender as ToolStripItem;
     if (menuItem != null)
     {
        // Retrieve the ContextMenuStrip that owns this ToolStripItem
        ContextMenuStrip owner = menuItem.Owner as ContextMenuStrip;
        if (owner != null)
        {
           // Get the control that is displaying this context menu
           Control sourceControl = owner.SourceControl;
        }
     }
 }

@bluefeet: फिर आपके पास कुछ और गलत है। मैंने इस कोड को तीन अलग-अलग लिस्टबॉक्स के साथ परीक्षण किया, और सब कुछ उम्मीद के मुताबिक काम किया। कुछ और repro कोड पोस्ट करें।
कोड़ी ग्रे

2
@bluefeet: मैंने अपने उत्तर में कोड अपडेट किया है। ContextMenuऔर के बीच एक बड़ा अंतर है ContextMenuStrip। (आह, और मैं देख रहा हूँ कि आपने पहले ही इसका पता लगा लिया है। खैर, सब कुछ अपने आप सीखने के लिए बेहतर है!)
कोडी ग्रे

1
मैंने सोर्सकंट्रोल को रिकॉर्ड करने के लिए ओपनिंग इवेंट का उपयोग किया, जिसने मेनू को एक स्थानीय वैरिएबल में खोला, और फिर संदर्भित किया कि आइटम क्लिक को हैंडल करते समय।
क्विकडेंजर

1
@QuickDanger हाँ, SourceControlइस समय Clickएक ToolStripItemउप-आइटम के एक घटना ContextMenuStripको निकाल दिया गया है , दुख की बात है। ऐसा लगता है कि ContextMenuStrip'एस Closedघटना आग से पहले कि Clickघटना है, जो शायद क्या समस्या का कारण बनता है; मुझे लगता है कि मेन्यू 'क्लोज' होने के बाद प्रॉपर्टी क्लियर हो जाती है।
Nyerguds

1
@ कोडिएजी दरअसल, अगर पेड़ अधिक गहरा है तो आपको OwnerItemसंपत्ति की श्रृंखला को लूप करना होगा जब तक ToolStripItemकि आपको यह पता न हो कि ContextMenuStripउसकी Ownerसंपत्ति में ए है । लेकिन जैसा कि मैंने अभी टिप्पणी की है, यह काम नहीं करता है; SourceControlसंदर्भ मेनू पर अशक्त हो जाएगा। आपने कहा कि आप इसे पुन: पेश नहीं कर सकते हैं ... हो सकता है कि समस्या केवल एक स्तर से अधिक गहरे मेनू के साथ हो? मेरा दो उप-स्तर गहरा था।
Nyerguds

3

पुराना पोस्ट, लेकिन अगर कोई अपने आप को इस तरह से देखता है:

एक ContextMenuStrip के लिए, ऊपर ने मेरे लिए काम नहीं किया, लेकिन इसने जो किया उसे खोजने का नेतृत्व किया।

void DeleteMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
    ContextMenuStrip menu = sender as ContextMenuStrip;
    Control sourceControl = menu.SourceControl;
    MessageBox.Show(sourceControl.Name);
}

इससे मुझे अपेक्षित नियंत्रण का नाम मिल गया। यदि आप बयान के साथ सत्यापन में डाल सकते हैं, तो मैं इस बिंदु पर पहुंचने के लिए पोस्ट कर रहा हूं।


यह केवल एक में प्रत्यक्ष वस्तुओं के साथ काम करता है ContextMenu। समस्या यह है कि उप-मेनू आइटम परItemClicked क्लिक करते समय आग न लगे ; उन्हें अपने स्वयं के ईवेंट की आवश्यकता होती है जिसमें आइटम स्वयं ही प्रेषक के रूप में होगा, मेनू नहीं। Click
Nyerguds

3

मुझे इस कोड को काम करने में बहुत कठिनाई हो रही थी। यह सबसे सरल उपाय है जो मैं पा सकता हूं:

एक संदर्भ के लिए

    Control _sourceControl = null;
    private void contextMenuStrip_Opened(object sender, EventArgs e)
    {
        _sourceControl = contextMenuStrip.SourceControl;
    }

    private void contextMenuItem_Click(object sender, EventArgs e)
    {
        var menuItem = (ToolStripMenuItem)sender;

        _sourceControl.Text = menuItem.Text;
        MessageBox.Show(menuItem.Name);
        MessageBox.Show(sourceControl.Name);
    }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.