问题
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