我想扩展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));
}
}
}
}
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));
}
}
}
}