Get source control of a clicked contextmenu combobox

926 Views Asked by At

I'm trying to grab the control that generated the context menu, as there will be several listview's using the same context menu.

I've done this before, but it appears to have gotten 1000x more complicated now I'm using an embedded combobox in the context menu:

enter image description here

When I select an item in the combo box, I need to determine which listview spawned the menu:

private void tsCboAddCharList_SelectedIndexChanged(object sender, EventArgs e) {
    if (tsCboAddCharList.SelectedItem == null) return;

    ContextMenuStrip theTSOwner;

    if (sender.GetType().Name.Contains("ToolStripComboBox")) {

        ToolStripComboBox theControl = sender as ToolStripComboBox;
        ToolStripDropDownMenu theMenu = theControl.Owner as ToolStripDropDownMenu;
        ContextMenuStrip theTlStrip = theMenu.OwnerItem.Owner as ContextMenuStrip;

        ContextMenuStrip theCtxStrip = theTlStrip as ContextMenuStrip;

        theTSOwner = theCtxStrip;
    } else {
        theTSOwner = (ContextMenuStrip)((ToolStripItem)sender).Owner;
    }

    ListView callingListV = (ListView)theTSOwner.SourceControl; //always null

What am I doing wrong?

1

There are 1 best solutions below

3
On

Try this code:

private void tsCboAddCharList_SelectedIndexChanged(object sender, EventArgs e)
{
    // Cast the sender to the ToolStripComboBox type:
    ToolStripComboBox cmbAddCharList = sender as ToolStripComboBox;

    // Return if failed:
    if (cmbAddCharList == null)
        return;

    if (cmbAddCharList.SelectedItem == null)
        return;

    // Cast its OwnerItem.Owner to the ContextMenuStrip type:
    ContextMenuStrip contextMenuStrip = cmbAddCharList.OwnerItem.Owner as ContextMenuStrip;

    // Return if failed:
    if (contextMenuStrip == null)
        return;

    // Cast its SourceControl to the ListView type:
    ListView callingListV = contextMenuStrip.SourceControl as ListView;
    // Note: it could be null if the SourceControl cannot be casted the type ListView.
}

If you are completely sure that this event handler can be called only for this particular menu item, you could omit the checks (but I'd not recommend this):

private void tsCboAddCharList_SelectedIndexChanged(object sender, EventArgs e)
{
    if (tsCboAddCharList.SelectedItem == null)
        return;

    // Cast the OwnerItem.Owner to the ContextMenuStrip type:
    ContextMenuStrip contextMenuStrip = (ContextMenuStrip)tsCboAddCharList.OwnerItem.Owner;

    // Cast its SourceControl to the ListView type:
    ListView callingListV = (ListView)contextMenuStrip.SourceControl;
}