C# How to remove custom TabControl border or header - c#

I have been experiencing an issue with my custom TabControl. I cannot remove a Border from the TabControl.
Here is the code of the TabControl.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Windows.Forms;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;
namespace GoatUserControls
{
public partial class GoatTab : TabControl
{
public static bool N_PositionMode;
public static bool N_PlusButton;
public GoatTab()
{
DrawMode = TabDrawMode.OwnerDrawFixed;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
DoubleBuffered = true;
SizeMode = TabSizeMode.Fixed;
ItemSize = new System.Drawing.Size(120, 30);
N_PositionMode = false;
N_PlusButton = false;
this.DrawMode = TabDrawMode.OwnerDrawFixed;
SetWindowTheme(this.Handle, "", "");
//var tab = new TabPadding(this);
}
[DllImportAttribute("uxtheme.dll")]
private static extern int SetWindowTheme(IntPtr hWnd, string appname, string idlist);
//All Properties
[Description("Desides if the Tab Control will display in vertical mode."), Category("Design"), Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
public bool VerticalMode{ get { return N_PositionMode; } set { N_PositionMode = value; if (N_PositionMode == true) { SetToVerticalMode(); } if (N_PositionMode == false) { SetToHorrizontalMode(); } }}
//Method for all of the properties
private void SetToHorrizontalMode(){ ItemSize = new System.Drawing.Size(120, 30); this.Alignment = TabAlignment.Top; }
private void SetToVerticalMode(){ ItemSize = new System.Drawing.Size(30, 120); Alignment = TabAlignment.Left; }
protected override void CreateHandle()
{
base.CreateHandle();
Alignment = TabAlignment.Top;
}
protected override void OnPaint(PaintEventArgs e)
{
Bitmap B = new Bitmap(Width, Height);
Graphics G = Graphics.FromImage(B);
G.Clear(Color.Gainsboro);
Color NonSelected = Color.FromArgb(62, 62, 62);
Color Selected = Color.FromArgb(0, 172, 219);
SolidBrush NOSelect = new SolidBrush(NonSelected);
SolidBrush ISSelect = new SolidBrush(Selected);
for (int i = 0; i <= TabCount - 1; i++)
{
Rectangle TabRectangle = GetTabRect(i);
if (i == SelectedIndex)
{
//Tab is selected
G.FillRectangle(ISSelect, TabRectangle);
}
else
{
//Tab is not selected
G.FillRectangle(NOSelect, TabRectangle);
}
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
Font font = new Font("Segoe UI", 10.0f);
G.DrawString(TabPages[i].Text, font, Brushes.White, TabRectangle, sf);
TabPages[i].BackColor = Color.FromArgb(62, 62, 62);
//TabPages[i].Padding = Point(0, 0);
}
e.Graphics.DrawImage(B, 0, 0);
G.Dispose();
B.Dispose();
base.OnPaint(e);
}
}
}
I think the Border is a background of the control. So most likely the question is how can I remove the background of a control. Do you guys have any ideas?

Related

Drawing on control

I have 3 layers (control "LayerControl" from here): image layer, drawing layer, and selection rectangle layer.
ImgEditor is a form for editing images (i'm making screenshooter and i want to add an image editor to it).
Layers are sorted in that order:
l3 - rectangle layer
l2 - drawing layer
l - image layer
Because l3 is top control, i must use callbacks MouseDown, MouseMove and MouseUp on it and then draw on l2 (drawing layer).
But when i'm trying to draw, i'm getting just nothing. Or, if i place l2 as the top layer, i'm getting this.
My code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SSTool
{
public partial class ImgEditor : Form
{
private Graphics g;
public Image _i;
public Brush gb = new SolidBrush(Color.Red);
public bool md = false;
public LayerControl l;
public LayerControl l2;
public LayerControl l3;
public Point? _Previous = null;
public ImgEditor(Image i, Rectangle r)
{
//l - main image
//l2 - drawing layer
//l3 - rectangle layer
InitializeComponent();
l = new LayerControl(i.Size);
l2 = new LayerControl(i.Size);
l3 = new LayerControl(i.Size);
this.Controls.Add(l3);
this.Controls.Add(l2);
this.Controls.Add(l);
l.Dock = DockStyle.Fill;
l2.Dock = DockStyle.Fill;
l3.Dock = DockStyle.Fill;
l2.Image = new Bitmap(i.Size.Width, i.Size.Height);
l3.MouseDown += new MouseEventHandler(l3_MouseDown);
l3.MouseMove += new MouseEventHandler(l3_MouseMove);
l3.MouseUp += new MouseEventHandler(l3_MouseUp);
_i = i;
l.Image = _i;
this.Size = _i.Size;
g = Graphics.FromImage(l3.Image);
g.Clear(Color.Transparent);
Pen p = new Pen(Color.FromArgb(180, 255, 0, 0));
Brush sb = new SolidBrush(Color.FromArgb(128, 211, 211, 211));
g.FillRectangle(sb, new Rectangle(0, 0, i.Size.Width, r.Location.Y)); //TOP
g.FillRectangle(sb, new Rectangle(0, r.Location.Y, r.Location.X, i.Size.Height - r.Location.Y)); //LEFT
g.FillRectangle(sb, new Rectangle(r.Location.X, r.Location.Y + r.Size.Height + 1, i.Size.Width - r.Location.X, i.Size.Height - r.Location.Y - r.Size.Height - 1)); //BOTTOM
g.FillRectangle(sb, new Rectangle(r.Location.X + r.Size.Width + 1, r.Location.Y, i.Size.Width - r.Location.X - r.Size.Width - 1, r.Size.Height + 1)); //RIGHT
g.DrawRectangle(p, r);
g.Dispose();
}
void l3_MouseUp(object sender, MouseEventArgs e)
{
_Previous = null;
}
void l3_MouseMove(object sender, MouseEventArgs e)
{
if (_Previous != null)
{
if (l2.Image == null)
{
Bitmap bmp = new Bitmap(l2.Width, l2.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
}
l2.Image = bmp;
}
using (Graphics g = Graphics.FromImage(l2.Image))
{
g.DrawLine(Pens.Black, _Previous.Value, e.Location);
}
l2.Invalidate();
_Previous = e.Location;
}
}
void l3_MouseDown(object sender, MouseEventArgs e)
{
_Previous = e.Location;
l3_MouseMove(sender, e);
}
}
public class LayerControl : UserControl
{
private Image image;
private Graphics graphics;
public LayerControl(Size s)
{
this.Width = s.Width;
this.Height = s.Height;
image = new Bitmap(s.Width, s.Height);
graphics = Graphics.FromImage(image);
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
var bitMap = new Bitmap(image);
image = bitMap;
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.GammaCorrected;
float[][] mtxItems = {
new float[] {1,0,0,0,0},
new float[] {0,1,0,0,0},
new float[] {0,0,1,0,0},
new float[] {0,0,0,1,0},
new float[] {0,0,0,0,1}};
ColorMatrix colorMatrix = new ColorMatrix(mtxItems);
ImageAttributes imgAtb = new ImageAttributes();
imgAtb.SetColorMatrix(
colorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap);
g.DrawImage(image,
ClientRectangle,
0.0f,
0.0f,
image.Width,
image.Height,
GraphicsUnit.Pixel,
imgAtb);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Graphics g = e.Graphics;
if (Parent != null)
{
BackColor = Color.Transparent;
int index = Parent.Controls.GetChildIndex(this);
for (int i = Parent.Controls.Count - 1; i > index; i--)
{
Control c = Parent.Controls[i];
if (c.Bounds.IntersectsWith(Bounds) && c.Visible)
{
Bitmap bmp = new Bitmap(c.Width, c.Height, g);
c.DrawToBitmap(bmp, c.ClientRectangle);
g.TranslateTransform(c.Left - Left, c.Top - Top);
g.DrawImageUnscaled(bmp, Point.Empty);
g.TranslateTransform(Left - c.Left, Top - c.Top);
bmp.Dispose();
}
}
}
else
{
g.Clear(Parent.BackColor);
g.FillRectangle(new SolidBrush(Color.FromArgb(255, Color.Transparent)), this.ClientRectangle);
}
}
public Image Image
{
get
{
return image;
}
set
{
image = value;
this.Invalidate();
}
}
}
}
Any ideas? I need to draw like with MS Paint brush.
I just had to invalidate layer l3 after drawing on layer l2.

Windows form combobox custom form color

I have been playing around with customizing the WinForm combobox...So far I have the following:
Using this code:
public class ComboBoxWithBorder : ComboBox
{
private Color _borderColor = Color.Black;
private ButtonBorderStyle _borderStyle = ButtonBorderStyle.Solid;
private static int WM_PAINT = 0x000F;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_PAINT)
{
Graphics g = Graphics.FromHwnd(Handle);
Rectangle bounds = new Rectangle(0, 0, Width, Height);
ControlPaint.DrawBorder(g, bounds, _borderColor, _borderStyle);
}
}
[Category("Appearance")]
public Color BorderColor
{
get { return _borderColor; }
set
{
_borderColor = value;
Invalidate(); // causes control to be redrawn
}
}
[Category("Appearance")]
public ButtonBorderStyle BorderStyle
{
get { return _borderStyle; }
set
{
_borderStyle = value;
Invalidate();
}
}
}
However, I am trying to achieve something similar to this:
Is it possible to change the background color of the white dropdown box to a darker color?
Is it possible to change the dropdown list border from white to a different color?
Try This Class
Refer
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class FlatCombo : ComboBox
{
private Brush BorderBrush = new SolidBrush(SystemColors.Window);
private Brush ArrowBrush = new SolidBrush(SystemColors.ControlText);
private Brush DropButtonBrush = new SolidBrush(SystemColors.Control);
private Color _ButtonColor = SystemColors.Control;
public Color ButtonColor {
get { return _ButtonColor; }
set {
_ButtonColor = value;
DropButtonBrush = new SolidBrush(this.ButtonColor);
this.Invalidate();
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(m);
switch (m.Msg) {
case 0xf:
//Paint the background. Only the borders
//will show up because the edit
//box will be overlayed
Graphics g = this.CreateGraphics;
Pen p = new Pen(Color.White, 2);
g.FillRectangle(BorderBrush, this.ClientRectangle);
//Draw the background of the dropdown button
Rectangle rect = new Rectangle(this.Width - 15, 3, 12, this.Height - 6);
g.FillRectangle(DropButtonBrush, rect);
//Create the path for the arrow
Drawing2D.GraphicsPath pth = new Drawing2D.GraphicsPath();
PointF TopLeft = new PointF(this.Width - 13, (this.Height - 5) / 2);
PointF TopRight = new PointF(this.Width - 6, (this.Height - 5) / 2);
PointF Bottom = new PointF(this.Width - 9, (this.Height + 2) / 2);
pth.AddLine(TopLeft, TopRight);
pth.AddLine(TopRight, Bottom);
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality;
//Determine the arrow's color.
if (this.DroppedDown) {
ArrowBrush = new SolidBrush(SystemColors.HighlightText);
} else {
ArrowBrush = new SolidBrush(SystemColors.ControlText);
}
//Draw the arrow
g.FillPath(ArrowBrush, pth);
break;
default:
break; // TODO: might not be correct. Was : Exit Select
break;
}
}
//Override mouse and focus events to draw
//proper borders. Basically, set the color and Invalidate(),
//In general, Invalidate causes a control to redraw itself.
#region "Mouse and focus Overrides"
protected override void OnMouseEnter(System.EventArgs e)
{
base.OnMouseEnter(e);
BorderBrush = new SolidBrush(SystemColors.Highlight);
this.Invalidate();
}
protected override void OnMouseLeave(System.EventArgs e)
{
base.OnMouseLeave(e);
if (this.Focused)
return;
BorderBrush = new SolidBrush(SystemColors.Window);
this.Invalidate();
}
protected override void OnLostFocus(System.EventArgs e)
{
base.OnLostFocus(e);
BorderBrush = new SolidBrush(SystemColors.Window);
this.Invalidate();
}
protected override void OnGotFocus(System.EventArgs e)
{
base.OnGotFocus(e);
BorderBrush = new SolidBrush(SystemColors.Highlight);
this.Invalidate();
}
protected override void OnMouseHover(System.EventArgs e)
{
base.OnMouseHover(e);
BorderBrush = new SolidBrush(SystemColors.Highlight);
this.Invalidate();
}
#endregion
}

How can put a Label on another Label

How can i put a label on another label and the text of them shows simultaneously?
When ever i do this work ,one of the labels goes top of another and the text of upper label shows.
Even i select BackColor = Transparent but it doesn't worked.
See Image below.
These are two labels and label1 goes under label2 and the text of label1 is missing.
And i want to have this result :
Just imagine i have two labels.one of them with 24pt font size,and another one is 8pt.
When i use larger Font ,the label has larger Frame than the other label.and i can't make them closer.
You can try this way:
label.Parent = parent with background
label.BackColor = Color.Transparent
label.Location = location you want offset with parent
Here is the converted code in C#:
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
public class TransparentLabel {
public TransparentLabel() {
// This call is required by the designer.
InitializeComponent();
// Add any initialization after the InitializeComponent() call.
// Add any initialization after the InitializeComponent() call.
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.Opaque, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.components = new System.ComponentModel.Container();
RF = new RectangleF(0, 0, base.Width, base.Height);
LabelForeColorBrush = new SolidBrush(base.ForeColor);
}
private StringFormat sFormat;
private RectangleF RF;
private SolidBrush LabelForeColorBrush = null;
private void UpdateText() {
try {
sFormat = new StringFormat();
int x = 0;
int y = 0;
// With...
switch (TextAlignment) {
case ContentAlignment.BottomCenter:
sFormat.Alignment = StringAlignment.Center;
sFormat.LineAlignment = StringAlignment.Far;
break;
case ContentAlignment.BottomLeft:
sFormat.Alignment = StringAlignment.Near;
sFormat.LineAlignment = StringAlignment.Far;
break;
case ContentAlignment.BottomRight:
sFormat.Alignment = StringAlignment.Far;
sFormat.LineAlignment = StringAlignment.Far;
break;
case ContentAlignment.MiddleLeft:
sFormat.Alignment = StringAlignment.Near;
sFormat.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.MiddleCenter:
sFormat.Alignment = StringAlignment.Center;
sFormat.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.MiddleRight:
sFormat.Alignment = StringAlignment.Far;
sFormat.LineAlignment = StringAlignment.Center;
break;
case ContentAlignment.TopCenter:
sFormat.Alignment = StringAlignment.Center;
sFormat.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.TopLeft:
sFormat.Alignment = StringAlignment.Near;
sFormat.LineAlignment = StringAlignment.Near;
break;
case ContentAlignment.TopRight:
sFormat.Alignment = StringAlignment.Far;
sFormat.LineAlignment = StringAlignment.Near;
break;
}
sFormat.FormatFlags = StringDirection;
ResizeControl();
}
catch (Exception ex) {
}
}
private void ResizeControl() {
RF.Size = new Size(base.Size);
Invalidate();
}
private StringFormatFlags _StringDirection = (StringFormatFlags.NoClip < Description("The Direction of the Text."));
public StringFormatFlags StringDirection {
get {
return _StringDirection;
}
set {
_StringDirection = value;
UpdateText;
}
}
private System.Drawing.ContentAlignment _TextAlignment = (ContentAlignment.MiddleCenter < Description("The Text Alignment that will appear on this control."));
public System.Drawing.ContentAlignment TextAlignment {
get {
return _TextAlignment;
}
set {
_TextAlignment = value;
UpdateText();
}
}
public override System.Drawing.Color ForeColor {
get {
return base.ForeColor;
}
set {
base.ForeColor = value;
LabelForeColorBrush = new SolidBrush(value);
}
}
private string _Labeltext = ("TransparentLabel" < Description("The text to be displayed in supports with real transparency."));
public string LabelText {
get {
return _Labeltext;
}
set {
_Labeltext = value;
Invalidate();
}
}
[Browsable(false)]
[EditorBrowsable(false)]
public override System.Drawing.Color BackColor {
get {
return base.BackColor;
}
set {
base.BackColor = value;
}
}
protected override System.Windows.Forms.CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle = (cp.ExStyle | 32);
return cp;
}
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
try {
base.OnPaint(e);
// draw the text on the control
e.Graphics.DrawString(LabelText, base.Font, LabelForeColorBrush, RF, sFormat);
// MyBase.OnPaint(e)
}
catch (Exception ex) {
}
}
private void TransparentLabel_Resize(object sender, System.EventArgs e) {
ResizeControl();
}
}
Winforms labels don't support transparency. You need to create your own label if you want to make that happen.
I don't know if I got your question right. But isn't label drop shadowing what you want?
If that is the case then you should check out this site: Label drop shadow
Small sample of usage:
using System;
using System.Drawing;
using System.Windows.Forms;
class WinFormsDropShadow: Form
{
public static void Main()
{
Application.Run(new WinFormsDropShadow());
}
public WinFormsDropShadow()
{
Text = "Windows Forms Drop Shadow";
BackColor = Color.White;
Size = new Size(640, 480);
}
protected override void OnPaint(PaintEventArgs args)
{
Graphics grfx = args.Graphics;
Font fnt = new Font("Arial Black", 96);
string str = "Shadow";
grfx.DrawString(str, fnt, Brushes.Gray, grfx.DpiX / 12, grfx.DpiY / 12);
grfx.DrawString(str, fnt, Brushes.Black, 0, 0);
}
}
This isn't labels, but it should get you what you're trying to achieve:
public void Form1()
{
Paint += Form1_Paint;
}
public void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(SystemColors.Control);
DrawOverlappingLabels(e, *new point for label 1*, *new point for label 2*);
}
private void DrawOverlappingLabels(PaintEventArgs e, _
Point positionLabel1, Point positionLabel2)
{
var graphics = e.Graphics();
var rectLabel1 = new Rectangle(new positionLabel1, new Size(150, 30));
var rectLabel2 = new Rectangle(new positionLabel2, new Size(150, 30));
graphics.DrawString("Label1", new Font(Font.FontFamily, 24f), _
new SolidBrush(Color.Black), rectLabel1);
graphics.DrawString("Label2", new Font(Font.FontFamily, 8f), _
new SolidBrush(Color.Black), rectLabel2);
}
Define a second Rectangle to tweak the positioning of the 2nd "label".

Creating a transparent picturebox class

My problem is that I want to put a picturebox with a png on a button, but WinForms doesn't seem to support transparency there.
1. Yes, I've tried Parent
2. Yes, I've tried Color.Transparent
The last try I had didn't work either and I'm kinda clueless about it. Maybe you can help me. However this is the closest try I had so far.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Parameter2
{
public class TransPicturebox : Control
{
public TransPicturebox()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint, true);
this.BackColor = Color.Transparent;
}
private Image _Image;
public Image Image
{
get
{
return _Image;
}
set
{
_Image = value;
}
}
private bool _autoscale = true;
public bool AutoScale
{
get
{
return _autoscale;
}
set
{
_autoscale = value;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (_Image != null) //keep from crashing if there is no image
{
if (_autoscale)
{
//Auto Scale the image to fit in the text box
Rectangle rectangle = new Rectangle();
Size size = this.Image.Size;
float num = Math.Min((float)(((float)base.ClientRectangle.Width) / ((float)size.Width)), (float)(((float)base.ClientRectangle.Height) / ((float)size.Height)));
rectangle.Width = (int)(size.Width * num);
rectangle.Height = (int)(size.Height * num);
rectangle.X = (base.ClientRectangle.Width - rectangle.Width) / 2;
rectangle.Y = (base.ClientRectangle.Height - rectangle.Height) / 2;
e.Graphics.DrawImage(_Image, rectangle);
}
else
{
e.Graphics.DrawImage(_Image, new Point(0, 0));
}
}
}
}
}

C# vertical label in a Windows Forms

Is it possible to display a label vertically in a Windows Forms?
Labels are easy, all you have to do is override the Paint event and draw the text vertically. Do note that GDI is optimised for Drawing text horizontally. If you rotate text (even if you rotate through multiples of 90 degrees) it will looks notably worse.
Perhaps the best thing to do is draw your text (or get a label to draw itself) onto a bitmap, then display the bitmap rotated.
Some C# code for drawing a Custom Control with vertical text. Note that ClearType text NEVER works if the text is not horizontal:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public partial class VerticalLabel : UserControl
{
public VerticalLabel()
{
InitializeComponent();
}
private void VerticalLabel_SizeChanged(object sender, EventArgs e)
{
GenerateTexture();
}
private void GenerateTexture()
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
format.Trimming = StringTrimming.EllipsisCharacter;
Bitmap img = new Bitmap(this.Height, this.Width);
Graphics G = Graphics.FromImage(img);
G.Clear(this.BackColor);
SolidBrush brush_text = new SolidBrush(this.ForeColor);
G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
G.DrawString(this.Name, this.Font, brush_text, new Rectangle(0, 0, img.Width, img.Height), format);
brush_text.Dispose();
img.RotateFlip(RotateFlipType.Rotate270FlipNone);
this.BackgroundImage = img;
}
}
Create a class myLabel which can rotate it's Text on any angle specified by you.
You can use it by code or simply dragging from ToolBox
using System.Drawing;
class myLabel:System.Windows.Forms.Label
{
public int RotateAngle { get; set; } // to rotate your text
public string NewText { get; set; } // to draw text
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Brush b =new SolidBrush(this.ForeColor);
e.Graphics.TranslateTransform(this.Width / 2, this.Height / 2);
e.Graphics.RotateTransform(this.RotateAngle);
e.Graphics.DrawString(this.NewText, this.Font,b , 0f, 0f);
base.OnPaint(e);
}
}
Now this custom control is used into your form.
You have to set below properties
1. mylbl.Text = ""; //which can be changed by NewText property
2. mylbl.AutoSize = false; // adjust according to your text
3. mylbl.NewText = "Hello"; // whatever you want to display
4. mylbl.ForeColor = Color.Red; // color to display
5. mylbl.RotateAngle = -90; //angle to rotate
I expanded on Javed Akram's answer to resize the widget automatically (I needed this feature). It works for both positive and negative angles, the way that Javed states:
1. mylbl.Text = ""; // which can be changed by NewText property
2. mylbl.AutoSize = false; // adjust according to your text
3. mylbl.NewText = "Hello"; // whatever you want to display
4. mylbl.ForeColor = Color.Red; // color to display
5. mylbl.RotateAngle = -90; // angle to rotate
Here is the code:
public class RotatingLabel : System.Windows.Forms.Label
{
private int m_RotateAngle = 0;
private string m_NewText = string.Empty;
public int RotateAngle { get { return m_RotateAngle; } set { m_RotateAngle = value; Invalidate(); } }
public string NewText { get { return m_NewText; } set { m_NewText = value; Invalidate(); } }
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Func<double, double> DegToRad = (angle) => Math.PI * angle / 180.0;
Brush b = new SolidBrush(this.ForeColor);
SizeF size = e.Graphics.MeasureString(this.NewText, this.Font, this.Parent.Width);
int normalAngle = ((RotateAngle % 360) + 360) % 360;
double normaleRads = DegToRad(normalAngle);
int hSinTheta = (int)Math.Ceiling((size.Height * Math.Sin(normaleRads)));
int wCosTheta = (int)Math.Ceiling((size.Width * Math.Cos(normaleRads)));
int wSinTheta = (int)Math.Ceiling((size.Width * Math.Sin(normaleRads)));
int hCosTheta = (int)Math.Ceiling((size.Height * Math.Cos(normaleRads)));
int rotatedWidth = Math.Abs(hSinTheta) + Math.Abs(wCosTheta);
int rotatedHeight = Math.Abs(wSinTheta) + Math.Abs(hCosTheta);
this.Width = rotatedWidth;
this.Height = rotatedHeight;
int numQuadrants =
(normalAngle >= 0 && normalAngle < 90) ? 1 :
(normalAngle >= 90 && normalAngle < 180) ? 2 :
(normalAngle >= 180 && normalAngle < 270) ? 3 :
(normalAngle >= 270 && normalAngle < 360) ? 4 :
0;
int horizShift = 0;
int vertShift = 0;
if (numQuadrants == 1)
{
horizShift = Math.Abs(hSinTheta);
}
else if (numQuadrants == 2)
{
horizShift = rotatedWidth;
vertShift = Math.Abs(hCosTheta);
}
else if (numQuadrants == 3)
{
horizShift = Math.Abs(wCosTheta);
vertShift = rotatedHeight;
}
else if (numQuadrants == 4)
{
vertShift = Math.Abs(wSinTheta);
}
e.Graphics.TranslateTransform(horizShift, vertShift);
e.Graphics.RotateTransform(this.RotateAngle);
e.Graphics.DrawString(this.NewText, this.Font, b, 0f, 0f);
base.OnPaint(e);
}
}
I found a way to simply do it without adding code or classes to your project!
When you create your label, simply add:
this.label1.text = "V\nE\nR\nT\nI\nC\nA\nL\n";
This worked for me!
You can rotate text instead of the label control in the OnPaint event or Paint method:
private void uc1_Paint(object sender, PaintEventArgs e)
{
string Name;
var g = e.Graphics;
g.DrawString(Name, new Font("Tahoma", 8), Brushes.Black, 0, 0,
new StringFormat(StringFormatFlags.DirectionVertical));
}
2015 update on an old post. Since most of the other answers seem to heavily affect VS2013's designer in terms of usability, I'd suggest this solution:
http://www.codeproject.com/Articles/19774/Extended-Vertical-Label-Control-in-C-NET
It absolutely works. I found it on net and little changed
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.ComponentModel;
public class VerticalLabel : System.Windows.Forms.Label
{
private bool bFlip = true;
public VerticalLabel()
{
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.Trimming = StringTrimming.None;
stringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
Brush textBrush = new SolidBrush(this.ForeColor);
Matrix storedState = g.Transform;
if (bFlip)
{
g.RotateTransform(180f);
g.TranslateTransform(-ClientRectangle.Width,-ClientRectangle.Height);
}
g.DrawString(
this.Text,
this.Font,
textBrush,
ClientRectangle,
stringFormat);
g.Transform = storedState;
}
[Description("When this parameter is true the VLabel flips at 180 degrees."),Category("Appearance")]
public bool Flip180
{
get
{
return bFlip;
}
set
{
bFlip = value;
this.Invalidate();
}
}
}
Used pieces from others
Jeremy
public partial class VerticalLabel_UserControl : UserControl
{
private IComponentChangeService _changeService;
private string strPropertyText = "Vertical Text";
public VerticalLabel_UserControl()
{
InitializeComponent();
}
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Bindable(true)]
public override string Text { get { return base.Text; } set { base.Text = value; this.Invalidate(); } }
private void VerticalLabel_UserControl_SizeChanged(object sender, EventArgs e)
{
GenerateTexture();
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
}
private void GenerateTexture()
{
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
// format.Trimming = StringTrimming.EllipsisCharacter;
Bitmap img = new Bitmap(this.Height, this.Width);
Graphics G = Graphics.FromImage(img);
G.Clear(this.BackColor);
SolidBrush brush_text = new SolidBrush(this.ForeColor);
G.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
G.DrawString(this.strPropertyText, this.Font, brush_text, new Rectangle(0, 0, img.Width, img.Height), format);
img.RotateFlip(RotateFlipType.Rotate270FlipNone);
this.BackgroundImage = img;
brush_text.Dispose();
}
public override System.ComponentModel.ISite Site
{
get
{
return base.Site;
}
set
{
_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (_changeService != null)
_changeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
base.Site = value;
if (!DesignMode)
return;
_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (_changeService != null)
_changeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
}
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs ce)
{
VerticalLabel_UserControl label = ce.Component as VerticalLabel_UserControl;
if (label == null || !label.DesignMode)
return;
if (((IComponent)ce.Component).Site == null || ce.Member == null || ce.Member.Name != "Text")
return;
//Causes the default text to be updated
string strName = this.Name.ToLower();
string strText = this.Text.ToLower();
if (strText.Contains(strName))
{
this.Text = "Vertical Text";
}
else
{
strPropertyText = this.Text;
}
//Prints the text vertically
GenerateTexture();
}
}
I just turned off the AutoSize property and resized the label vertically. I made the label wide enough for only one character. Then I changed TextAlign to center to make the alignment look better. This worked great for me.

Categories

Resources