ContextMenuStripが使用されたコントロールを決定します


84

ContextMenuStripいくつかの異なるリストボックスに割り当てられているがあります。ContextMenuStripがクリックされたときに何ListBoxが使用されたかを把握しようとしています。以下のコードを最初に試しましたが、機能しません。sender正しい値を持っているが、私はそれを割り当てるしようとすると、menuSubmittedそれがnullです。

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レベルにネストしたくない場合は使用することをお勧めします。
Shawn Kovac 2013年

回答:


123

の場合ContextMenu

問題は、senderパラメータが、コンテキストメニュー自体ではなく、クリックされたコンテキストメニューの項目を指していることです。

ただし、それぞれがそのメニュー項目を含むメソッドMenuItem公開するため、これは簡単な修正です。GetContextMenuContextMenu

コードを次のように変更します。

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。2つのコントロールは相互に関連しておらず、一方のインスタンスをもう一方のインスタンスにキャストすることはできません。

以前と同様に、クリックされたアイテムは引き続き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:それならあなたは何か他の問題があります。このコードを3つの異なるリストボックスでテストしたところ、すべてが期待どおりに機能しました。さらにいくつかの再現コードを投稿してください。
コーディグレイ

2
@bluefeet:回答のコードを更新しました。との間には大きな違いがContextMenuありContextMenuStripます。(ああ、あなたはすでにそれを理解しているようです。まあ、自分で物事を学ぶ方がいいです!)
CodyGray

1
Openingイベントを使用して、メニューを開いたSourceControlをローカル変数に記録し、アイテムのクリックを処理するときにそれを参照しました。
QuickDanger 2017年

1
@QuickDangerええ、のサブアイテムのイベントが発生SourceControlした瞬間、悲しいことにnullです。これは、と思われるのイベントが発生する前にその問題を引き起こすもので、おそらくイベント、。メニューが「閉じた」後にプロパティがクリアされたと思います。ClickToolStripItemContextMenuStripContextMenuStripClosedClick
Nyerguds 2018年

1
ツリーは、より深いあなたがのチェーンアップループに持っている場合、実際に@CodyGrayOwnerItemあなたが見つけるまで性質ToolStripItemがあることContextMenuStrip、その中にOwnerプロパティを。しかし、私がコメントしたように、それは機能しません。SourceControlコンテキストメニューにはnullになります。あなたはそれを再現することはできないと言いました...多分問題は1レベルより深いメニューでのみ発生しますか?鉱山は2つのサブレベルの深さでした。
Nyerguds

3

古い投稿ですが、私のような誰かがそれに遭遇した場合:

ContextMenuStripの場合、上記は機能しませんでしたが、何が機能するかを見つけることにつながりました。

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

これにより、予想されるコントロールの名前がわかりました。ifステートメントを使用して検証などを行うことができます。要点を理解するために投稿しています。


これは、内の直接アイテムでのみ機能しContextMenuます。問題は、サブメニュー項目をItemClickedクリックしても起動しないことです。メニューではなく、アイテム自体を送信者として持つ独自のイベントが必要です。Click
Nyerguds

3

このコードを機能させるのに非常に苦労しました。これは私が見つけることができる最も簡単な解決策です:

ContextMenuStripの場合:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.