Bender
Bender

Reputation: 523

How to get the name of a control that has started an event?

I need to get the name of the control that's start an event, in particular I've used a ContextMenu for DataGrid, this is the code that I actually write:

private void ClearTable_Click(object sender, RoutedEventArgs e)
{
    // Try to cast the sender to a MenuItem
    ContextMenu menuItem = sender as ContextMenu;
    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;
    }
}

XAML

 <ContextMenu x:Key="Squadre_ContextMenu">
            <MenuItem Header="Pulisci Tabella" Click="ClearTable_Click">
            </MenuItem>
            <MenuItem Header="Elimina Riga selezionata" Click="ClearRow_Click">
            </MenuItem>
        </ContextMenu>

but the ContextMenu doesn't have the method GetContextMenu, so this is a problem for me. There's a way to fix this or another way to do this?

Upvotes: 1

Views: 1465

Answers (4)

Nevca
Nevca

Reputation: 204

Try this:

private void ClearTable_Click(object sender, RoutedEventArgs e)
{
    // Try to cast the sender to a Control
    Control ctrl = sender as Control;
    if (ctrl != null)
    {
        // Get the control name
        string name = ctrl.Name;

        // Get parent control name
        Control parent = (Control) ctrl.Parent;
        string parentName = parent.Name
    }
}

EDIT: added code to get parent control's name

Upvotes: 2

Liero
Liero

Reputation: 27338

Ok, first of all, you have bug in your code. your menuItem variable will be always null, because sender is MenuItem actually, since you assigned ClearTable_Click to MenuItem, not ContextMenu.

Second, in order to get ContextMenu from MenuItem, you need to look at VisualTree and search for MenuItem's parent of type context menu. There is API called VisualTreeHelper.GetParent(). Alternativelly, you can use GetSelfAndAncestors helper method from System.Windows.Interactivity.dll:

using System.Windows.Interactivity;

private void ClearTable_Click(object sender, RoutedEventArgs e)
{
    var menuItem = (MenuItem)sender; //MenuItem that fired the click event
    var contextMenu = menuItem.GetSelfAndAncestors().OfType<ContextMenu>().First()
    UIElement sourceControl = menu.PlacementTarget;
}

Upvotes: 0

Claudio_G
Claudio_G

Reputation: 61

I made a form with a datagridview and I get the name with no problems

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            int l_Index = 0;

            InitializeComponent();

            MenuItem[] l_MenuItems = new MenuItem[3];

            for (l_Index = 0; l_Index < l_MenuItems.Length; l_Index++)
            {
                l_MenuItems[l_Index] = new MenuItem("Menu " + l_Index.ToString(), MenuItem_Click);
            }

            System.Windows.Forms.ContextMenu l_ContextMenu = new ContextMenu(l_MenuItems);

            dataGridView1.ContextMenu = l_ContextMenu;
        }

        private void MenuItem_Click(object sender, EventArgs e)
        {
            MenuItem l_MenuItem = sender as MenuItem;

            if (l_MenuItem != null)
            {
                System.Windows.Forms.ContextMenu l_ContextMenu = l_MenuItem.GetContextMenu();

                if (l_ContextMenu != null)
                {
                    if (l_ContextMenu.SourceControl != null)
                    {
                        System.Diagnostics.Debug.WriteLine(l_ContextMenu.SourceControl.Name);
                    }
                }
            }
        }

        private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                dataGridView1.ContextMenu.Show(dataGridView1, new Point(e.X, e.Y));
            }
        }
    }
}

Upvotes: 0

carcanholo
carcanholo

Reputation: 161

An example taking the sender object as MenuItem and then getting the ContextMenu for a TextBlock control:

MenuItem mi = sender as MenuItem;

if (mi != null)
{
    ContextMenu cm = mi.CommandParameter as ContextMenu;

    if (cm != null)
    {
        TextBlock t = cm.PlacementTarget as TextBlock;
        if (t != null)
        {
            // print t.Name or whatever...
        }
    }
}

Hope this helps

Upvotes: 0

Related Questions