Using Graphics.DrawImage to create custom tabs in C#

╄→гoц情女王★ 提交于 2020-01-07 03:51:45

问题


I have a project in which you can add and remove tabs (like a web browser). So far I have this:

//Button to add a new tab page
    private void cb_addPage_Click(object sender, EventArgs e)
    {
        string title = "TabPage " + (tabControl1.TabCount + 1).ToString() + "   ";
        TabPage myTabPage = new TabPage(title);
        tabControl1.TabPages.Add(myTabPage);
        tabControl1.SelectedTab = myTabPage;
    }


//Form1_Load
    private void Form1_Load(object sender, EventArgs e)
    {
        tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
        cb_addPage.Top = tabControl1.Top;
        cb_addPage.Left = tabControl1.Right - cb_addPage.Width;
        foreach (TabPage tp in tabControl1.TabPages) tp.Text += "   ";
    }

    Rectangle closeX = Rectangle.Empty;

//Sets background and places the X button on each tab
    private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
    {
        Size xSize = new Size(15, 15);
        TabPage tp = tabControl1.TabPages[e.Index];
        e.DrawBackground();
        using (SolidBrush brush = new SolidBrush(e.ForeColor))
            e.Graphics.DrawString(tp.Text + "   ", e.Font, brush,
                                  e.Bounds.X + 3, e.Bounds.Y + 4);

        if (e.State == DrawItemState.Selected)
        {
            closeX = new Rectangle(e.Bounds.Right - xSize.Width - 3, 
                           e.Bounds.Top + 5, xSize.Width, xSize.Height);
            e.Graphics.DrawImage(imageList1.Images[0], closeX, 
                         new Rectangle(0,0,16,16), GraphicsUnit.Pixel );
        }

    }

//Removes current tab (from X button)
    private void tabControl1_MouseClick(object sender, MouseEventArgs e)
    {
        if (closeX.Contains(e.Location))
            tabControl1.TabPages.Remove(tabControl1.SelectedTab);
    }

So all this does is let you add tabs with a button and on each individual tab there is an X button to delete the tab.

I have used Graphics.DrawImage to display the custom X button (that are in an imageList). However how will I go about making custom tabs using Graphics.DrawImage.

To sum up I want tabs, but I want them to be custom images that I have made so it looks better. - Thanks


回答1:


Your question is not very clear. Probably you want to display a different text on each tab. You can use the TextRenderer to do so:

const TextFormatFlags flags = TextFormatFlags.PreserveGraphicsClipping |
    TextFormatFlags.VerticalCenter;

TextRenderer.DrawText(e.Graphics, tp.Text, tp.Font, e.Bounds, tp.ForeColor, flags);

Either prepend some spaces to the text in order to leave space for the X or define new coordiantes for the text

const int XCrossWidth = 20;
Rectangle textRect = new Rectangle(e.Bounds.Left + XCrossWidth,  e.Bounds.Top,
                                   e.Width - XCrossWidth, e.Height);

and substitue this for e.Bounds in TextRenderer.DrawText(...).


UPDATE

So you want to display custom images on your tabs. I assume that you have placed these images in the imageList1. How do you know which of them to display on which TabPage?

You could create your own tab page class and use this one instead of TabPage.

public TabPageEx : TabPage
{
    public int ImageIndex { get; set }
}

Now set the property to the appropriate image index.

TabPageEx myTabPage = new TabPageEx(title);
myTabPage.ImageIndex = 3; // As an example.
tabControl1.TabPages.Add(myTabPage);

Then you can draw the image with

TabPageEx tp = (TabPageEx)tabControl1.TabPages[e.Index];

...

Rectangle imageRect = new Rectangle(e.Bounds.Left + 20,  0, 16, 16);
e.Graphics.DrawImage(imageList1.Images[tp.ImageIndex], imageRect);



回答2:


If you want to display Images in addition to the text like a webbrowsers favicon you can use this modified code:

private void tabControl3_DrawItem(object sender, DrawItemEventArgs e)
{
    Size xSize = new Size(16,16);
    Point imgLoc = new Point(e.Bounds.X +  4, e.Bounds.Y + 4);
    TabPage tp = tabControl3.TabPages[e.Index];
    e.DrawBackground();
    e.Graphics.DrawImage(imageList1.Images[tp.ImageIndex], new Rectangle(imgLoc, xSize), 
                            new Rectangle(Point.Empty, xSize), GraphicsUnit.Pixel);

    using (SolidBrush brush = new SolidBrush(e.ForeColor))
    {
        e.Graphics.DrawString(tp.Text + "   ", e.Font, brush, 
                              e.Bounds.X + 23, e.Bounds.Y + 4);
        if (e.State == DrawItemState.Selected)
        {
            closeX = new Rectangle(e.Bounds.Right - xSize.Width - 3, 
                         e.Bounds.Top + 5, xSize.Width, xSize.Height);
            e.Graphics.DrawImage(imageList1.Images[0], closeX, 
                       new Rectangle(Point.Empty, xSize), GraphicsUnit.Pixel);

        }
    }
}

You need to make sure that:

  • You have those images you want to show in each tab in your imagelist.
  • and you know the index of ech one.
  • Youi must set it when you create the page but you can always change it later.
  • It is a good idea to have a default icon at index 0 and to set the imageindex to 0 for those you don't know the right index.

Usually you would also have to make your Tab control point to the Imagelist. But since we are drawing it all by ourselves, this is not important.

You can use the more complex format of DrawString, that is used for drawing the close button. Here you don't just use a point to determine the location where to draw; instead this format uses two rectangles to determine the source and the target. This effectively leads to th option of scaling the image to a new size.

But you'll get the best quality if your Images have the right size to begin with. Please note that the text of each TabPage determines the width of the tab; to make it higher you need to chose a larger Fontsize.



来源:https://stackoverflow.com/questions/26327942/using-graphics-drawimage-to-create-custom-tabs-in-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!