문제

Windows Forms 앱에서는 tabcontrol에 ContextMenustrip 속성을 설정했습니다.

  1. 사용자가 현재 선택된 것보다 다른 탭을 클릭했다고 어떻게 말할 수 있습니까?
  2. 레이블이있는 상단 탭 부분이 탭의 다른 곳이 아닌 다른 곳이 아닌 경우에만 컨텍스트 메뉴가 표시되지 않도록하려면 어떻게해야합니까?
도움이 되었습니까?

해결책

TabControl에서 ContextMenustrip 속성을 설정하지 마십시오. 오히려 이런 식으로하십시오. TabControl의 MouseClick 이벤트에 연결 한 다음 컨텍스트 메뉴를 수동으로 표시하십시오. 실제 페이지가 아닌 상단의 탭 자체가 클릭하면 발생합니다. 페이지를 클릭하면 TabControl은 클릭 이벤트를받지 못합니다. 일부 코드 :

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);
    }


}

다른 팁

컨텍스트 메뉴의 열기 이벤트를 사용하여 두 문제를 해결할 수 있습니다.

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.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을 가지고있었습니다).

  • tabcontrol1을 만듭니다
  • Mouseclick 이벤트를 구독하십시오
  • ContextMenutabs, ContextMenustrip을 만듭니다


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.tabControl1GetTabRect(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;
            }
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top