我该如何正确地放置上下文菜单,当我右键点击一个DataGridView的列标题?当我、上下文、我该、正确地

2023-09-03 10:48:54 作者:痴梦

我想扩展DataGridView中添加第二个文本菜单其中选择哪些列在网格中可见。新文本菜单将显示在单击列标题的右侧。

我有困难得到正确的水平位置,以显示上下文菜单。我怎样才能解决这个?

 公共部分类Form1中:形态
{
    DataGridView中的数据网格;
    的ContextMenuStrip的ContextMenuStrip;

    公共Form1中()
    {
        的InitializeComponent();

        dataGrid的=新的DataGridView();
        Controls.Add被(dataGrid的);
        dataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
        dataGrid.ColumnHeaderMouseClick + =新System.Windows.Forms.DataGridViewCellMouseEventHandler(ColumnHeaderMouseClick);
        dataGrid.DataSource =新字典<字符串,字符串>()了ToList()。

        的ContextMenuStrip =新的ContextMenuStrip();
        contextMenuStrip.Items.Add(富);
        contextMenuStrip.Items.Add(巴);
    }

    私人无效ColumnHeaderMouseClick(对象发件人,DataGridViewCellMouseEventArgs E)
    {
        如果(e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            contextMenuStrip.Show(PointToScreen(e.Location));
        }
    }
}
 

解决方案

我要去哪里错了是DataGridViewCellMouseEventArgs返回上鼠标点击在的列标题的位置/ X,Y。相反,我需要的列标题上使用的HitTest在网格中的MouseDown事件一击,然后转换成命中的位置从网格坐标到屏幕坐标。

 公共部分类Form1中:形态
{
    DataGridView中的数据网格;
    的ContextMenuStrip的ContextMenuStrip;

    公共Form1中()
    {
        的InitializeComponent();

        dataGrid的=新的DataGridView();
        Controls.Add被(dataGrid的);
        dataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
        //dataGrid.ColumnHeaderMouseClick + = ColumnHeaderMouseClick;
        dataGrid.MouseDown + =的MouseDown;
        dataGrid.DataSource =新字典<字符串,字符串>()了ToList()。

        的ContextMenuStrip =新的ContextMenuStrip();
        contextMenuStrip.Items.Add(富);
        contextMenuStrip.Items.Add(巴);
    }

    私人无效ColumnHeaderMouseClick(对象发件人,DataGridViewCellMouseEventArgs E)
    {
        如果(e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            contextMenuStrip.Show(PointToScreen(e.Location));
        }
    }

    私人无效的MouseDown(对象发件人,发送MouseEventArgs E)
    {
        如果(e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            如果(dataGrid.HitTest(例如,EY)。键入== DataGridViewHitTestType.ColumnHeader)
            {
                contextMenuStrip.Show(dataGrid.PointToScreen(e.Location));
            }
        }
    }
}
 

如何从Win11右键单击上下文菜单中删除 在Windows终端中打开

I would like to extended DataGridView to add a second ContextMenu which to select what columns are visible in the gird. The new ContextMenu will be displayed on right click of a column's header.

I am having difficulty get the correct horizontal position to show the context menu. How can I correct this?

public partial class Form1 : Form
{
    DataGridView dataGrid;
    ContextMenuStrip contextMenuStrip;        

    public Form1()
    {
        InitializeComponent();

        dataGrid = new DataGridView();
        Controls.Add(dataGrid);
        dataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
        dataGrid.ColumnHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(ColumnHeaderMouseClick);
        dataGrid.DataSource = new Dictionary<string, string>().ToList();

        contextMenuStrip = new ContextMenuStrip();
        contextMenuStrip.Items.Add("foo");
        contextMenuStrip.Items.Add("bar");
    }

    private void ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            contextMenuStrip.Show(PointToScreen(e.Location));
        }
    }
}

解决方案

Where I was going wrong was that DataGridViewCellMouseEventArgs returns the location/x,y of where the mouse clicked within the column header. Instead I need to use HitTest in the grid's MouseDown event for a hit on the column headers and then convert the position of the hit from the gird co-ordinates to the screen co-ordinates.

public partial class Form1 : Form
{
    DataGridView dataGrid;
    ContextMenuStrip contextMenuStrip;        

    public Form1()
    {
        InitializeComponent();

        dataGrid = new DataGridView();
        Controls.Add(dataGrid);
        dataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
        //dataGrid.ColumnHeaderMouseClick += ColumnHeaderMouseClick;
        dataGrid.MouseDown += MouseDown;
        dataGrid.DataSource = new Dictionary<string, string>().ToList();

        contextMenuStrip = new ContextMenuStrip();
        contextMenuStrip.Items.Add("foo");
        contextMenuStrip.Items.Add("bar");
    }

    private void ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            contextMenuStrip.Show(PointToScreen(e.Location));
        }
    }

    private void MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            if (dataGrid.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.ColumnHeader)
            {
                contextMenuStrip.Show(dataGrid.PointToScreen(e.Location));
            }
        }
    }
}