tabControl中的关闭按钮

时间:2010-07-06 03:32:34

标签: c# winforms tabcontrol

有没有人可以告诉我如何在C#中使用tabControl在每个标签中添加关闭按钮? 我计划使用按钮图片替换我标签中的[x] ..

谢谢

4 个答案:

答案 0 :(得分:53)

如果没有派生类,这里有一个简洁的片段: http://www.dotnetthoughts.net/implementing-close-button-in-tab-pages/

将Tab Control的DrawMode属性设置为OwnerDrawFixed。此属性决定系统或开发人员是否可以绘制字幕。 在Tab控件的DrawItem事件中添加代码 - 将调用此事件来绘制每个Tab页面。

    //This code will render a "x" mark at the end of the Tab caption. 
e.Graphics.DrawString("x", e.Font, Brushes.Black, e.Bounds.Right - 15, e.Bounds.Top + 4);
e.Graphics.DrawString(this.tabControl1.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + 12, e.Bounds.Top + 4);
e.DrawFocusRectangle();

现在,对于关闭按钮操作,我们需要将以下代码添加到Tab控件的MouseDown事件中。

//Looping through the controls.
for (int i = 0; i < this.tabControl1.TabPages.Count; i++)
{
    Rectangle r = tabControl1.GetTabRect(i);
   //Getting the position of the "x" mark.
    Rectangle closeButton = new Rectangle(r.Right - 15, r.Top + 4, 9, 7);
    if (closeButton.Contains(e.Location))
    {
        if (MessageBox.Show("Would you like to Close this Tab?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
        {
            this.tabControl1.TabPages.RemoveAt(i);
            break;
        }
    }
}

答案 1 :(得分:7)

添加其他答案...当我们只能使用.SelectedIndex和.SelectedTab检测当前选项卡时,为什么要遍历鼠标单击事件的所有选项卡?

像这样:

using Widgets;

namespace Client
{
    public class Client
    {
        public static void Main(string[] args)
        {
            IWidget blueWidget = new WidgetFactory().BuildBlue();
            IWidget otherBlueWidget = new BlueWidget(); // doesn't compile
        }
    }
}

似乎发生的事情是,当您单击tabPage关闭它时,它也会被选中,从而允许关闭按钮关闭右侧tabPage。 对我来说它有效,但请特别小心,因为我不完全确定可能的缺点(我的初始句子不是一个完全修辞的问题,因为我对.Net有点新鲜......)。

答案 2 :(得分:1)

试试这段代码:

    private Point _imageLocation = new Point(13, 5);
        private Point _imgHitArea = new Point(13, 2);

        private void Form1_Load(object sender, EventArgs e)
        {
            tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
    tabControl1.DrawItem += tabControl1_DrawItem;
    CloseImage = WindowsFormsApplication3.Properties.Resources.closeR;
    tabControl1.Padding = new Point(10, 3);
        }


    private void TabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
        {
            try
            {
                Image img = new Bitmap(CloseImage);
                Rectangle r = e.Bounds;
                r = this.tabControl1.GetTabRect(e.Index);
                r.Offset(2, 2);
                Brush TitleBrush = new SolidBrush(Color.Black);
                Font f = this.Font;
                string title = this.tabControl1.TabPages[e.Index].Text;

                e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y));

                if (tabControl1.SelectedIndex >= 1)
                {
                    e.Graphics.DrawImage(img, new Point(r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
                }
            }
            catch (Exception) { }
        }


private void TabControl1_Mouse_Click(object sender, System.Windows.Forms.DrawItemEventArgs e)
{

TabControl tc = (TabControl)sender;
Point p = e.Location;
int _tabWidth = 0;
_tabWidth = this.tabControl1.GetTabRect(tc.SelectedIndex).Width - (_imgHitArea.X);
Rectangle r = this.tabControl1.GetTabRect(tc.SelectedIndex);
r.Offset(_tabWidth, _imgHitArea.Y);
r.Width = 16;
r.Height = 16;
if (tabControl1.SelectedIndex >= 1)
{
    if (r.Contains(p))
    {
        TabPage TabP = (TabPage)tc.TabPages[tc.SelectedIndex];
        tc.TabPages.Remove(TabP);
    }

}
}

查看this代码段

答案 3 :(得分:0)

我遇到了同样的问题,但是,我也想在选项卡上标题的前面放置一个图像。这是将为您提供正面图像,标题和关闭按钮的代码。此外,此代码还包括使用鼠标中键单击选项卡将其关闭的功能。

首先在TabControl的属性下将DrawMode从Normal更改为OwnerDrawFixed。接下来,您需要调整X尺寸,也可以在属性下找到TabControl的填充。

在此示例中,我的TabControl称为“ TabManager”,因此将其重命名为控件的名称。

进入到实体下(属性框顶部附近的小闪电),然后双击“ DrawItem”旁边的白色框,这将创建一个触发器。在这种方法中,请在调整时使用此代码。

return StreamBuilder<QuerySnapshot>(
  stream: Firestore.instance.collection('productlist').where('productid', isEqualTo: pid).limit(1),
  builder: (context, snapshot) {
    if (snapshot.data != null) {
      // Here u will get list of document snapshots
      final List<DocumentSnapshot> documents = snapshot.data.documents;
      // now u can access each document by simply specifying its number
      // u can also use list view to display every one of them
      return ListView.builder(
        itemCount: documents.length,
        itemBuilder: (context, int index) => Text(documents[index]['productname']),
      );
    } else {
      // Show loading indicator here
    }
  },
);

接下来,返回事件并双击MouseDown旁边的白框。然后使用以下代码:

    private void TabManager_DrawItem(object sender, DrawItemEventArgs e)
    {
        TabPage thisTab = TabManager.TabPages[e.Index];
        string tabTitle = thisTab.Text;
        Image icon = imageList1.Images[thisTab.ImageIndex];
        //Draw Close button
        Point closeLoc = new Point(15, 5);
        e.Graphics.DrawRectangle(Pens.Black, e.Bounds.Right - closeLoc.X, e.Bounds.Top + closeLoc.Y, 10, 12);
        e.Graphics.FillRectangle(Brushes.LightBlue, e.Bounds.Right - closeLoc.X, e.Bounds.Top + closeLoc.Y, 10, 12);
        e.Graphics.DrawString("x", e.Font, Brushes.Black, e.Bounds.Right - (closeLoc.X), e.Bounds.Top + closeLoc.Y-2);
        // Draw String of Caption
        e.Graphics.DrawString(tabTitle, e.Font, Brushes.Black, e.Bounds.Left + 28, e.Bounds.Top + 4);
        // Add Icon to Front
        e.Graphics.DrawImage(icon, e.Bounds.Left + 6, e.Bounds.Top + 3);
        e.DrawFocusRectangle();
    }