Since I'm a C# beginner I don't know what's to do in my case. I wanted a side-aligned tab control so I have found this:
https://msdn.microsoft.com/en-us/library/ms404305%28v=vs.110%29.aspx
Now the tabpage names are not getting displayed at all. How do I "draw" them? I hope someone can help me. The DrawItem method:
private void tabControl1_DrawItem(object sender, 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.Red);
g.FillRectangle(Brushes.Gray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
Related
I changed in the properties OwnerDraw to true.
and added the Draw event.
private void toolTip1_Draw(object sender, DrawToolTipEventArgs e)
{
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
sf.FormatFlags = StringFormatFlags.NoWrap;
using (Font f = new Font("Tahoma", 12))
{
e.Graphics.DrawString(e.ToolTipText, f,
SystemBrushes.ActiveCaptionText, e.Bounds, sf);
}
}
}
First time i put the mouse over a control with a tooltip the text is bigger but then next on other controls the tooltip get black :
before using the Draw event it was working fine but i want to resize the text font size.
You need clear the graphics first.
e.Graphics.Clear(((Control)sender).BackColor);
Or just use the methods defined in DrawToolTipEventArgs
e.DrawBackground();
e.DrawBorder();
I have a custom user control with a picture box on it. Then, draw a circle on the control in Paint event.
var size = TextRenderer.MeasureText(this.UnreadCount.ToString(), lblDisplayname.Font);
var rec = new Rectangle(0, 0, size.Width, size.Width);
var smallFont = new Font(lblDisplayname.Font.Name, lblDisplayname.Font.Size - 1);
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
format.LineAlignment = StringAlignment.Center;
using (LinearGradientBrush b = new LinearGradientBrush(
rec,
Color.FromArgb(242, 37, 37),
Color.FromArgb(178, 30, 30),
45F))
{
e.Graphics.FillEllipse(b, rec);
e.Graphics.DrawString(this.UnreadCount.ToString(), smallFont, Brushes.White, rec, format);
}
Then, later in the implementation, I set the image of the control's picture box.
MyControl ctrl = new MyControl();
ctrl.picImage.Image = Image.FromFile(imagePath);
ctrl.Refresh();
The issue is that: the picture box's image overlap the drawn circle.
current issue
Requirement is that: The circle is needed to display fully overlapping the image. What might be causing my issue?
The following fuction will return a user control with your requirements ,Posting the code for you to understand the parent child relationship.
Either the graphics has to be drawn on top of the image container or on another transparent container that is on top of the image.
The below sample has 2 panels ,panel1 and panel2 where panel 2 is a child of panel.
Panel1 is the background image and panel 2 has the graphics.Hope it helps.
private UserControl create_MyControl( string filenamepath)
{
//Create User Control
UserControl MyControl = new UserControl();
//Mention the size of control
MyControl.Size = new Size(100, 100);
//Create a panel to hold the background image that you wanted in the picture box
Panel panel1 = new Panel();
//dock the panel1 to fill the control background
panel1.Dock = DockStyle.Fill;
MyControl.Controls.Add(panel1);
//Create another panel as overlay for panel1
Panel panel2 = new Panel();
//dock the panel2 to fill the panel1;
panel2.Dock = DockStyle.Fill;
//Add panel2 as child of panel1
panel1.Controls.Add(panel2);
//Set panel2 background as transparent
panel2.BackColor = Color.Transparent;
// To replicate the variables that you have!
Label lblDisplayname = new Label();
lblDisplayname.Font = new Font("Arial", 24, FontStyle.Regular);
lblDisplayname.Size = panel2.Size;
lblDisplayname.TextAlign = ContentAlignment.TopCenter;
lblDisplayname.Text = "25";
lblDisplayname.Dock = DockStyle.Fill;
panel2.Controls.Add(lblDisplayname);
panel1.BackgroundImage = Image.FromFile(filenamepath);
panel1.BackgroundImageLayout = ImageLayout.Stretch;
//In Panel2 paint event put your code for stuff
panel2.Paint += (s, e) =>
{
var size = TextRenderer.MeasureText("Hello", lblDisplayname.Font);
var rec = new Rectangle(0, 0, size.Width, size.Width);
var smallFont = new Font(lblDisplayname.Font.Name, lblDisplayname.Font.Size - 1);
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
format.LineAlignment = StringAlignment.Center;
using (System.Drawing.Drawing2D.LinearGradientBrush b = new System.Drawing.Drawing2D.LinearGradientBrush(
rec,
Color.FromArgb(242, 37, 37),
Color.FromArgb(178, 30, 30),
45F))
{
e.Graphics.FillEllipse(b, rec);
e.Graphics.DrawString("Hello", smallFont, Brushes.White, rec, format);
}
};
return MyControl;
}
I have created a custom control and bind it to Form. I have draw graphics text in the control and added to Form. But it was not displaying the Form. This is my code.
//Create a custom control
public class DrawTextImage : Control
{
public void DrawBox(PaintEventArgs e, Size size)
{
e.Graphics.Clear(Color.White);
int a = 0;
SolidBrush textColor = new SolidBrush(Color.Black);
using (SolidBrush brush = new SolidBrush(Color.Red))
{
e.Graphics.FillRectangle(brush, new Rectangle(a, a, size.Width, size.Height));
e.Graphics.DrawString("Text", Font, textColor, new PointF(50, 50));
}
}
}
//Load Form1
public Form1()
{
InitializeComponent();
DrawTextImage call = new DrawTextImage();
call.Text = "TextControl";
call.Name = "TextContrl";
Size siz = new Size(200, 100);
call.Location = new Point(0, 0);
call.Visible = true;
call.Size = siz;
call.DrawBox(new PaintEventArgs(call.CreateGraphics(), call.ClientRectangle), siz);
this.Controls.Add(call);
}
Any help on this, what did I do wrong?
You should be using the control's own Paint event, not a custom method that you have to call manually.
public class DrawTextImage : Control
{
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
int a = 0;
SolidBrush textColor = new SolidBrush(Color.Black);
using (SolidBrush brush = new SolidBrush(Color.Red))
{
//Note: here you might want to replace the Size parameter with e.Bounds
e.Graphics.FillRectangle(brush, new Rectangle(a, a, Size.Width, Size.Height));
e.Graphics.DrawString("Text", Font, textColor, new PointF(50, 50));
}
}
}
Remove the call to DrawBox, it's unnecessary.
The Paint event is fired automatically whenever a redraw of the control surface is required. You can ask for this yourself in code by using the control's Invalidate() or Refresh() methods.
I want to display some information in tab control This is what I want.
I have used the methods that I found on your side to make changes in properties of tab control and using Draw Event but the output is not like what i needed.The output comes likeThis is what I am getting..
I want the text to be horizontal. Also my VS is 2008
I followed these instructions in VB and converted them to C#. Worked for me. Basically in tab control properties set the following:
Alignment = Left
SizeMode = Fixed
ItemSize = 30, 120: Width = 30 Height = 120
DrawMode = OwnerDrawFixed
Then you have to handle DrawItem event like that:
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
var g = e.Graphics;
var text = this.tabControl1.TabPages[e.Index].Text;
var sizeText = g.MeasureString(text, this.tabControl1.Font);
var x = e.Bounds.Left + 3;
var y = e.Bounds.Top + (e.Bounds.Height - sizeText.Height) / 2;
g.DrawString(text, this.tabControl1.Font, Brushes.Black, x, y);
}
And the result is:
Set the SizeMode property to Fixed, so that all tabs are the same width.
Set the ItemSize property to the preferred fixed size for the tabs. Keep in mind that the ItemSize property behaves as though the tabs were on top, although they are left-aligned. As a result, in order to make the tabs wider, you must change the Height property, and in order to make them taller, you must change the Width property. [I set the ItemSize as: 25, 150].
Set the DrawMode property to OwnerDrawFixed.
private void tabControl1_DrawItem(object sender, 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.Red);
g.FillRectangle(Brushes.Gray, e.Bounds);
}
else
{
_textBrush = new System.Drawing.SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new StringFormat();
_stringFlags.Alignment = StringAlignment.Center;
_stringFlags.LineAlignment = StringAlignment.Center;
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
While trying to change the color of the tab based on button click event I came across this page:
Set TabPage Header Color
It appears to work, however I lost all the other formatting of my tabs and they now appear blank after I set the DrawMode=OwnerDrawFixed. How do I set the color of the tab of a specific page and still show the tabs as normal?
Code:
private void button3_Click(object sender, EventArgs e)
{
this.TabControlMain.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.TabControlMain_DrawItem);
SetTabHeader (tabDownload, System.Drawing.Color.Green);
}
private Dictionary<TabPage, Color> TabColors = new Dictionary<TabPage, Color>();
private void SetTabHeader(TabPage page, Color color)
{
TabColors[page] = color;
tabDownload.Invalidate();
}
private void TabControlMain_DrawItem(object sender, DrawItemEventArgs e)
{
//e.DrawBackground();
using (Brush br = new SolidBrush(TabColors[TabControlMain.TabPages[e.Index]]))
{
e.Graphics.FillRectangle(br, e.Bounds);
SizeF sz = e.Graphics.MeasureString(TabControlMain.TabPages[e.Index].Text, e.Font);
e.Graphics.DrawString(TabControlMain.TabPages[e.Index].Text, e.Font, Brushes.Black, e.Bounds.Left + (e.Bounds.Width - sz.Width) / 2, e.Bounds.Top + (e.Bounds.Height - sz.Height) / 2 + 1);
Rectangle rect = e.Bounds;
rect.Offset(0, 1);
rect.Inflate(0, -1);
e.Graphics.DrawRectangle(Pens.DarkGray, rect);
e.DrawFocusRectangle();
}
}
Below is a screenshot
Use Y(et)A(nother)TabControl
Gives you the possibly to draw own custom headers:
public override void DrawTab( Color foreColor,
Color backColor,
Color highlightColor,
Color shadowColor,
Color borderColor,
bool active,
bool mouseOver,
DockStyle dock,
Graphics graphics,
SizeF tabSize )
{
if( active )
{
Pen p = new Pen( borderColor );
graphics.DrawRectangle( p, 0, 0, tabSize.Width, tabSize.Height );
p.Dispose();
}
else
{
Brush b = Brushes.Peru;
float dif = tabSize.Height / 4.0f;
RectangleF r = new RectangleF( 0.0f, dif,
tabSize.Width, tabSize.Height - dif - dif );
graphics.FillRectangle( b, r );
}
}
In principle your code works, if not fine then at least sufficiently.
But you need to fix a few simple issues:
Of course, if your Tab is OwnerDrawn you need to do it from the start, not just after pressing the Button! So hook up the event right from the start, best in the Property-Event Tab so that it is placed in the Desgner.cs file where it belongs.
Now the Tabs are drawn and their Label texts show.
If you want to change a color you need to Invalidate the Tab Control, not the TabPage!
so change
tabDownload.Invalidate();
to
TabControlMain.Invalidate();
To make the example complete I have done only this:
private void Form1_Load(object sender, EventArgs e)
{
foreach (TabPage tp in TabControlMain.TabPages)
TabColors.Add(tp, tp.BackColor);
}
This sets all Tab colors in the Dictionary to the Colors of the Pages.
The code to draw the FocusRectangle could be improved.
First set the Padding like this:
this.TabControlMain.Padding = new System.Drawing.Point(10, 4);
This gives us enough room to draw a nice FocusRectangle..
Then change the code to draw it only on the selected Tab, maybe like this:
if (TabControlMain.SelectedIndex == e.Index)
using (Pen pen = new Pen(Color.Gray))
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
Rectangle rect = e.Bounds;
rect.Offset(0, 1);
rect.Inflate(-3,-2);
e.Graphics.DrawRectangle(pen, rect);
}
Now it looks like this:
Of course managing the colors is up to you..