I have followed the instructions in the msdn website:
https://msdn.microsoft.com/en-us/library/vstudio/ms404305%28v=vs.100%29.aspx
to display a tab control as the following picture:
And this is the code:
private void tcMain_DrawItem(Object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
TabPage _tabPage = tcMain.TabPages[e.Index];
Rectangle _tabBounds = tcMain.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.Gray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
Font _tabFont = new Font("Times New Roman", (float)22, FontStyle.Regular, GraphicsUnit.Pixel);
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Near;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
Now I want to add a picture to the left of the tab control buttons? I mean, how to show a picture to the left of the word Book for example?
After trying some answers from below I ended up with the code:
private void tcMain_DrawItem(Object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
TabPage _tabPage = tcMain.TabPages[e.Index];
Rectangle _tabBounds = tcMain.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected)
{
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.Gray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
tcMain.ImageList = imgList;
tcMain.TabPages[0].ImageIndex = 1;
tcMain.TabPages[1].ImageIndex = 0;
tcMain.TabPages[2].ImageIndex = 3;
tcMain.TabPages[3].ImageIndex = 2;
Rectangle tabImage = tcMain.GetTabRect(e.Index);
tabImage.Size = new Size(40, 40);
g.DrawImage(tcMain.ImageList.Images[_tabPage.ImageIndex], tabImage);
Font _tabFont = new Font("Times New Roman", (float)22, FontStyle.Regular, GraphicsUnit.Pixel);
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
Then when I take a snapshot to the results it comes like this:
Refreshing all the time
You could add an ImageList control to your project and add some images to it and set the ImageIndex property of your TabPages. Then just use DrawImage() method in your DrawItem event.
Rectangle tabImage = tcMain.GetTabRect(e.Index);
tabImage.Size = new Size(16, 16);
g.DrawImage(tcMain.ImageList.Images[_tabPage.ImageIndex], tabImage);
You could also use ImageKey instead of ImageIndex.
g.DrawImage(tcMain.ImageList.Images[_tabPage.ImageKey], tabImage);
If you add the ImageList and the ImageIndex programmatically take a look:
ImageList imageList = new ImageList();
imageList.Images.Add("key1", Image.FromFile("pathtofile"));
imageList.Images.Add("key2", Image.FromFile("pathtofile"));
tcMain.ImageList = imageList;
tcMain.TabPages[0].ImageIndex = 1;
tcMain.TabPages[1].ImageIndex = 0;
Related
I need to add WedgeRectCallout callout on picturebox using C#.
Is there a way to do it?
please refer image using below link to know about the callout.
In word document, I can do the same using Spire.Doc library and writing below code:
ShapeObject Shape1 = para1.AppendShape(30, 50, ShapeType.WedgeRectCallout);
Here is a minimal example. It creates a Panel subclass with a nested TextBox.
Note that you can't add controls to a PictureBox in the designer. Instead you can put it on top and use the Nest function to embed it in the PBox..
(I use a trick to simplify the drawing of the border: since shrinking a GraphicsPath is hard and I am too lazy to write out two of them, I draw the border twice and add a little offset. The effect is a shadow effect, which looks rather nice for a cheat..)
Here is the class in action:
And here is the class code:
class WedgeCallout : Panel
{
public WedgeCallout()
{
tb = new TextBox();
Controls.Add(tb);
}
TextBox tb = null;
GraphicsPath gp = new GraphicsPath();
protected override void OnLayout(LayoutEventArgs levent)
{
tb.Size = new Size(Width - 10, (int)(Height * 0.66));
tb.Location = new Point(5, 5);
tb.BackColor = BackColor;
tb.ForeColor = ForeColor ;
tb.BorderStyle = BorderStyle.None;
tb.Text = "Hiho";
tb.Multiline = true;
tb.TextAlign = HorizontalAlignment.Center;
tb.Font = Font;
SetRegion();
base.OnLayout(levent);
}
protected override void OnBackColorChanged(EventArgs e)
{
base.OnBackColorChanged(e);
if (BackColor != Color.Transparent)
tb.BackColor = BackColor;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (Tag == null) return;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using(SolidBrush brush = new SolidBrush(tb.BackColor))
e.Graphics.FillPath(brush, (GraphicsPath)Tag);
using (Pen pen = new Pen(Color.DarkGray, 2f))
e.Graphics.DrawPath(pen, (GraphicsPath)Tag);
e.Graphics.TranslateTransform(-1, -1);
using (Pen pen = new Pen(ForeColor, 2f))
e.Graphics.DrawPath(pen, (GraphicsPath)Tag);
}
void SetRegion()
{
Rectangle r = ClientRectangle;
int h = (int)(r.Height * 0.75f);
if (gp != null) gp.Dispose();
gp = new GraphicsPath();
gp.AddPolygon(new PointF[]{ new Point(0,0),
new Point(r.Width-1, 0), new Point(r.Width-1, h),
new PointF(50, h) , new Point(0, r.Height-1),
new PointF(20, h), new PointF(0, h)});
Region = new Region(gp);
Tag = gp;
}
}
You can set the colors and the Font in the designer..
And the Nest function:
void Nest(Control child, Control parent)
{
Point p0 = parent.PointToScreen(Point.Empty);
Point p1 = child.PointToScreen(Point.Empty);
child.Location = new Point(p1.X - p0.X, p1.Y - p0.Y);
child.Parent = parent;
}
It is called from the Form where the controls sit: Nest(wedgeCallout1, pictureBox1);
Note that to save to callout with the pbox in one image you need to
Nest the callout in the PBox
Use pbox.DrawToBitmap
Temporarily set the backcolor to transparent
Example:
private void saveBtn_Click(object sender, EventArgs e)
{
Size sz = pictureBox1.ClientSize;
using (Bitmap bmp = new Bitmap(sz.Width, sz.Height))
{
Color old = wedgeCallout1.BackColor;
wedgeCallout1.BackColor = Color.Transparent;
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save(filename, ImageFormat.Png);
wedgeCallout1.BackColor = old;
}
}
I need to put two lines as text in a WinForms button so I have found this solution. I need first line, that above, to be printed in black color, and second line, that under the first one, to be printed in red color. My problem is that background rectangle is not transparent. I need background rectangle to be transparent so I have done some improvements but without success. Also first line is printed at the top not at center (vertical) and the distance between two lines (line spacing) there is too much separation. I would like to reduce it as well and center in vertical the two lines within the button. Below the code.
private void TextButton(Button btn, string line1, string line2)
{
btn.Text = String.Empty;
Bitmap bmp = new Bitmap(btn.ClientRectangle.Width, btn.ClientRectangle.Height);
using (Graphics G = Graphics.FromImage(bmp))
{
G.Clear(btn.BackColor);
StringFormat SF = new StringFormat();
SF.Alignment = StringAlignment.Center;
SF.LineAlignment = StringAlignment.Near;
using (Font tahoma = new Font("Tahoma", 15.75F, System.Drawing.FontStyle.Bold))
{
Rectangle RC = btn.ClientRectangle;
RC.Inflate(-5, -5);
G.FillRectangle(Brushes.Transparent,RC.X,RC.Y,RC.Width,RC.Height);
G.DrawString(line1, tahoma, Brushes.Black, RC, SF);
}
using (Font tahoma2 = new Font("Tahoma", 12))
{
SF.LineAlignment = StringAlignment.Center;
G.FillRectangle(Brushes.Transparent,btn.ClientRectangle.X,btn.ClientRectangle.Y,btn.ClientRectangle.Width,btn.ClientRectangle.Height);
G.DrawString(line2, tahoma2, Brushes.Red, btn.ClientRectangle, SF);
}
}
btn.Image = bmp;
btn.ImageAlign = ContentAlignment.MiddleCenter;
}
Finally I have solved. Below my solution.
private void TextButton(Button btn, string line1, string line2)
{
btn.Text = String.Empty;
Bitmap bmp = new Bitmap(btn.ClientRectangle.Width, btn.ClientRectangle.Height);
using (Graphics G = Graphics.FromImage(bmp))
{
G.Clear(Color.Transparent); <----- I have set this
G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; <--- This to avoid bad text within bitmap
G.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; <--- Also this to avoid bad text within bitmap
StringFormat SF = new StringFormat();
SF.Alignment = StringAlignment.Center;
SF.LineAlignment = StringAlignment.Near;
using (Font tahoma = new Font("Tahoma", 15.75F, System.Drawing.FontStyle.Bold))
{
Rectangle RC = new Rectangle(btn.ClientRectangle.X, btn.ClientRectangle.Y + 30, btn.ClientRectangle.Width, btn.ClientRectangle.Height-30);
RC.Inflate(-5, -5);
G.DrawString(line1, tahoma, Brushes.Black, RC, SF);
}
using (Font tahoma2 = new Font("Tahoma", 12))
{
Rectangle RC = new Rectangle(btn.ClientRectangle.X, btn.ClientRectangle.Y + 30, btn.ClientRectangle.Width, btn.ClientRectangle.Height-30);
RC.Inflate(-5, -5);
SF.LineAlignment = StringAlignment.Center;
G.DrawString(line2, tahoma2, Brushes.Red, RC, SF);
}
}
btn.Image = bmp;
btn.ImageAlign = ContentAlignment.MiddleCenter;
}
I have a problem with the font of the TabControl.
I set the Alignment to Left, and use following code to set the font:
private void tabControl1_DrawItem(Object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Brush _textBrush;
// Get the item from the collection.
TabPage _tabPage = tabControl1.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
if (e.State == DrawItemState.Selected) {
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Black);
g.FillRectangle(Brushes.LightSkyBlue, e.Bounds);
}
else {
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Calibri", (float)11.0, FontStyle.Regular, GraphicsUnit.Pixel);
// Draw string. Left the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Near;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
I set the font to "Calibri", (float)11.0, but the text in the tabcontrol are smaller. Please refer to the following:
Font Error
What should I do to set the correct font?
Really appreciate your help!
Eric
Background Color of the panel control is set to color gradient.
and i want to set same panel backcolor and label pack color
my code is same below
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics g = panel1.CreateGraphics();
LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(0, 0, this.panel1.Width, this.panel1.Height), Color.Black, Color.Black, LinearGradientMode.Horizontal);
ColorBlend cb = new ColorBlend();
cb.Colors = new Color[] { Color.Black, Color.White };
cb.Positions = new Single[] { 0.0F, 1.0F };
lgb.InterpolationColors = cb;
g.FillRectangle(lgb, new Rectangle(0, 0, this.panel1.Width, this.panel1.Height));
label1.Parent = panel1;
label1.BackColor = Color.Transparent;
lgb.Dispose();
g.Dispose();
}
Which part was wrong?
There is a problem with the line below:
Graphics g = panel1.CreateGraphics();
Change it to:
Graphics g = e.Graphics;
And you can also put the following codes in the constructor (to avoid reassigning whenever panel is Invalidated):
label1.Parent = panel1;
label1.BackColor = Color.Transparent;
Ex
|Tab1|Tab2|Tab3| { }
| |
| |
| |
| |
|_____________________|
I am able to change the backcolor and forecolor of Tab.. but I want to change the color of that { } -- > Empty space is this possible to do that. .. It shows default winforms color..help me in dis..
private void Form1_Load(object sender, EventArgs e)
{
}
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Font fntTab;
Brush bshBack;
Brush bshFore;
if ( e.Index == this.tabControl1.SelectedIndex)
{
fntTab = new Font(e.Font, FontStyle.Bold);
bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, SystemColors.Control, SystemColors.Control, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
bshFore = Brushes.Black;
//bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, Color.LightSkyBlue , Color.LightGreen, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
//bshFore = Brushes.Blue;
}
else
{
fntTab = e.Font;
bshBack = new SolidBrush(Color.Red);
bshFore = new SolidBrush(Color.Aqua);
//bshBack = new SolidBrush(Color.White);
//bshFore = new SolidBrush(Color.Black);
}
string tabName = this.tabControl1.TabPages[e.Index].Text;
StringFormat sftTab = new StringFormat();
e.Graphics.FillRectangle(bshBack, e.Bounds);
Rectangle recTab = e.Bounds;
recTab = new Rectangle( recTab.X, recTab.Y + 4, recTab.Width, recTab.Height - 4);
e.Graphics.DrawString(tabName, fntTab, bshFore, recTab, sftTab);
}
Try adding the following code to your DrawItem event handler. Don't forget to set the DrawMode to "OwnerdrawFixed".
You might have to tweak it a bit to cover some margins which aren't painted.
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
SolidBrush fillbrush= new SolidBrush(Color.Red);
//draw rectangle behind the tabs
Rectangle lasttabrect = tabControl1.GetTabRect(tabControl1.TabPages.Count - 1);
Rectangle background = new Rectangle();
background.Location = new Point(lasttabrect.Right, 0);
//pad the rectangle to cover the 1 pixel line between the top of the tabpage and the start of the tabs
background.Size = new Size(tabControl1.Right - background.Left, lasttabrect.Height+1);
e.Graphics.FillRectangle(fillBrush, background);
}
'This answer is much better than prior one. But the tabCtrl is not defined. It has to be tabControl1 control.
I think the only way to give that space a color is to override the OnPaintBackground method of the window, so just paste this on your form (window)
you must also change the Appearance Property to "Normal"
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Rectangle lasttabrect = tabControl1.GetTabRect(tabControl1.TabPages.Count - 1);
RectangleF emptyspacerect = new RectangleF(
lasttabrect.X + lasttabrect.Width + tabControl1.Left,
tabControl1.Top + lasttabrect.Y,
tabControl1.Width - (lasttabrect.X + lasttabrect.Width),
lasttabrect.Height);
Brush b = Brushes.BlueViolet; // the color you want
e.Graphics.FillRectangle(b, emptyspacerect );
}
for me it's working perfectly
you can also create a custom tabcontrol as you did
public class mytab : TabControl
{
public mytab()
: base()
{
this.DrawMode = TabDrawMode.OwnerDrawFixed;
this.DrawItem += new DrawItemEventHandler(tabControl1_DrawItem);
}
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
Font fntTab;
Brush bshBack;
Brush bshFore;
if (e.Index == this.SelectedIndex)
{
fntTab = new Font(e.Font, FontStyle.Bold);
bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, SystemColors.Control, SystemColors.Control, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
bshFore = Brushes.Black;
//bshBack = new System.Drawing.Drawing2D.LinearGradientBrush(e.Bounds, Color.LightSkyBlue , Color.LightGreen, System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);
//bshFore = Brushes.Blue;
}
else
{
fntTab = e.Font;
bshBack = new SolidBrush(Color.Red);
bshFore = new SolidBrush(Color.Aqua);
//bshBack = new SolidBrush(Color.White);
//bshFore = new SolidBrush(Color.Black);
}
string tabName = this.TabPages[e.Index].Text;
StringFormat sftTab = new StringFormat();
e.Graphics.FillRectangle(bshBack, e.Bounds);
Rectangle recTab = e.Bounds;
recTab = new Rectangle(recTab.X, recTab.Y + 4, recTab.Width, recTab.Height - 4);
e.Graphics.DrawString(tabName, fntTab, bshFore, recTab, sftTab);
Rectangle r = this.GetTabRect(this.TabPages.Count - 1);
RectangleF tf =
new RectangleF(r.X + r.Width,
r.Y-5, this.Width - (r.X + r.Width)+5, r.Height+5);
Brush b = Brushes.BlueViolet;
e.Graphics.FillRectangle(b, tf);
}
}