在 Windows 窗体应用程序中,我在 TabControl 上设置了 ContextMenuStrip 属性。
- 如何告诉用户单击了当前选择的选项卡以外的选项卡?
- 如何限制上下文菜单仅在单击带有标签的顶部选项卡部分时才显示,而不是在选项卡的其他位置显示?
在 Windows 窗体应用程序中,我在 TabControl 上设置了 ContextMenuStrip 属性。
上下文菜单的打开事件可以用来解决这两个问题
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
Point p = this.tabControl1.PointToClient(Cursor.Position);
for (int i = 0; i < this.tabControl1.TabCount; i++)
{
Rectangle r = this.tabControl1.GetTabRect(i);
if (r.Contains(p))
{
this.tabControl1.SelectedIndex = i; // i is the index of tab under cursor
return;
}
}
e.Cancel = true;
}
不要费心在 TabControl 上设置 contextMenuStrip 属性。而是这样做。连接到 tabControl 的 MouseClick 事件,然后手动显示上下文菜单。这只会在单击顶部的选项卡本身而不是实际页面时触发。如果单击页面,则 tabControl 不会收到单击事件,而 TabPage 会收到。一些代码:
public Form1()
{
InitializeComponent();
this.tabControl1.MouseClick += new MouseEventHandler(tabControl1_MouseClick);
}
private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.contextMenuStrip1.Show(this.tabControl1, e.Location);
}
}
有点晚了,但我已经为你的问题的第一部分找到了解决方案。您可以通过向应用程序发送鼠标左键单击来确定右键单击了哪个选项卡。这将选择选项卡,因此现在您可以使用 TabControl.SelectedTab 属性来获取用户右键单击的选项卡。
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
private static void SendLeftMouseClick()
{
int x = Cursor.Position.X;
int y = Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, x, y, 0, 0);
}
public Form1()
{
InitializeComponent();
tabControl1.MouseDown += new MouseEventHandler(tabControl1_MouseDown);
tabControl1.MouseUp += new MouseEventHandler(tabControl1_MouseUp);
}
void tabControl1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
// Send a left mouse click to select the tab that the user clicked on.
SendLeftMouseClick();
}
}
void tabControl1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
// To show a context menu for only the tab button but not the content of the tab,
// we must show it in the tab control's mouse up event.
contextMenuStrip1.Show((Control)sender, e.Location);
}
}
我一直在为完全相同的问题寻找解决方案。
在测试了@nisar 和@BFree 的答案后,我得出了这个结论(我在表单的某个地方的面板中也有 TabControl`):
private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Point ee = new Point(e.Location.X - panel1.Left, e.Location.Y - panel1.Top);
for (int i = 0; i < this.tabControl1.TabCount; i++)
{
Rectangle r = this.tabControl1.GetTabRect(i);
if (r.Contains(ee))
{
if (this.tabControl1.SelectedIndex == i)
this.contextMenuTabs.Show(this.tabControl1, e.Location);
else
{
//if a non seelcted page was clicked we detected it here!!
}
break;
}
}
}
}