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));
}
}
}
}
}
Related
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?
I was wanting to get an image to fill a picture box, but not leaving any whitespace. Thus cutting off parts of the image to fit when its not resized to the aspect ratio of the pictureBox. And to adjust as the user resizes the window/pictureBox. The existing options, Sizemode = Zoom leaves whitespace, as its afraid to cut off any of the image and Sizemode = StretchImage stretches the image, distorting it.
The only way I can think of doing this is creating an algorithm to resize the image, keeping the contrast ratio, and setting the width or length of the image to the pictureBox width or length and creating some runtime loop which runs the algorithm once a frame. It seems kind of performance heavy for what it does and kind of hackish. Is there a better option?
Edit:
For anyone coming by, I implemented Ivan Stoev's solution slightly differently:
class ImageHandling
{
public static Rectangle GetScaledRectangle(Image img, Rectangle thumbRect)
{
Size sourceSize = img.Size;
Size targetSize = thumbRect.Size;
float scale = Math.Max((float) targetSize.Width / sourceSize.Width, (float) targetSize.Height / sourceSize.Height);
var rect = new RectangleF();
rect.Width = scale * sourceSize.Width;
rect.Height = scale * sourceSize.Height;
rect.X = (targetSize.Width - rect.Width) / 2;
rect.Y = (targetSize.Height - rect.Height) / 2;
return Rectangle.Round(rect);
}
public static Image GetResizedImage(Image img, Rectangle rect)
{
Bitmap b = new Bitmap(rect.Width, rect.Height);
Graphics g = Graphics.FromImage((Image) b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(img, 0, 0, rect.Width, rect.Height);
g.Dispose();
try
{
return (Image)b.Clone();
}
finally
{
b.Dispose();
b = null;
g = null;
}
}
public Form1()
{
InitializeComponent();
updateMainBackground();
}
void updateMainBackground()
{
Image img = Properties.Resources.BackgroundMain;
Rectangle newRect = ImageHandling.GetScaledRectangle(img, mainBackground.ClientRectangle);
mainBackground.Image = ImageHandling.GetResizedImage(img, newRect);
}
private void Form1_Resize(object sender, EventArgs e)
{
updateMainBackground();
}
}
If I understand correctly, you are seeking for a "Fill" mode (similar to Windows background picture). There is no standard way of doing that, but it's not so hard to make your own with the help of a small calculation and GDI+:
using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
namespace Samples
{
public class ImageFillBox : Control
{
public ImageFillBox()
{
SetStyle(ControlStyles.Selectable | ControlStyles.SupportsTransparentBackColor, false);
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.Opaque | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
}
private Image image;
public Image Image
{
get { return image; }
set
{
if (image == value) return;
image = value;
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (image == null)
e.Graphics.Clear(BackColor);
else
{
Size sourceSize = image.Size, targetSize = ClientSize;
float scale = Math.Max((float)targetSize.Width / sourceSize.Width, (float)targetSize.Height / sourceSize.Height);
var rect = new RectangleF();
rect.Width = scale * sourceSize.Width;
rect.Height = scale * sourceSize.Height;
rect.X = (targetSize.Width - rect.Width) / 2;
rect.Y = (targetSize.Height - rect.Height) / 2;
e.Graphics.DrawImage(image, rect);
}
}
}
static class Test
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var testForm = new Form();
testForm.Controls.Add(new ImageFillBox
{
Dock = DockStyle.Fill,
Image = GetImage(#"http://www.celebrityrockstarguitars.com/rock/images/Metall_1.jpg")
});
Application.Run(testForm);
}
static Image GetImage(string path)
{
var uri = new Uri(path);
if (uri.IsFile) return Image.FromFile(path);
using (var client = new WebClient())
return Image.FromStream(new MemoryStream(client.DownloadData(uri)));
}
}
}
According to the PictureBoxSizeMode documentation you can specify PictureBoxSizeMode.Zoom to get the image to keep its aspect ratio. It will zoom as big as possible without any part of the image overflowing the picture box.
And you can play with the Dock property (setting DockStyle.Full) to get the picture box to resize to the size of its container.
There is a fairly simple solution to this. PictureBox.SizeMode has a few settings that will help us out. Zoom will adjust the image to fit in the box and Normal will place the picture with out resizing. What we will want to do is check the height and width of the image and if it is larger than the PictureBox size we will Zoom, if not, we will place it in with Normal. See below:
if (image.Height > pctbx_ImageRecognition.Height || image.Width > pctbx_ImageRecognition.Width)
pctbx_ImageRecognition.SizeMode = PictureBoxSizeMode.Zoom;
else
pctbx_ImageRecognition.SizeMode = PictureBoxSizeMode.Normal;
hello I am making an application that the design requires special graphs that change depending on the value that is give. like this:
how would i go about doing this? could someone point me in the right direction?
the outer ring of the orange changes with the value but the middle circle stays static.
p.s my paint skills are amazing.
You can draw your own control quite easily. The main thing is the FillPie method, which draws only part of a circle. To change the starting point of the outer ring or the filling direction you need to change the starting and sweep angle in the FillPie call of the OnPaint event.
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
public class CircularProgressBar : Control
{
#region "Properties"
private Color _BorderColor;
public Color BorderColor
{
get { return _BorderColor; }
set
{
_BorderColor = value;
this.Invalidate();
}
}
private Color _InnerColor;
public Color InnerColor
{
get { return _InnerColor; }
set
{
_InnerColor = value;
this.Invalidate();
}
}
private bool _ShowPercentage;
public bool ShowPercentage
{
get { return _ShowPercentage; }
set
{
_ShowPercentage = value;
this.Invalidate();
}
}
private int _BorderWidth;
public int BorderWidth
{
get { return _BorderWidth; }
set
{
_BorderWidth = value;
this.Invalidate();
}
}
private float _Value;
public float Value
{
get { return _Value; }
set
{
_Value = value;
this.Invalidate();
}
}
#endregion
#region "Constructor"
public CircularProgressBar()
{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
_Value = 100;
_BorderColor = Color.Orange;
_BorderWidth = 30;
_ShowPercentage = true;
_InnerColor = Color.DarkGray;
this.ForeColor = Color.White;
}
#endregion
#region "Painting"
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//Measure the single parts
int Diameter = Math.Min(this.ClientSize.Width, this.ClientSize.Height);
int InnerDiameter = Diameter - BorderWidth;
Rectangle PieRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - Diameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - Diameter / 2), Diameter, Diameter);
Rectangle InnerRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - InnerDiameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - InnerDiameter / 2), InnerDiameter, InnerDiameter);
//Draw outer ring
using (SolidBrush b = new SolidBrush(BorderColor))
{
e.Graphics.FillPie(b, PieRect, 0, Value / 100 * 360);
}
//Draw inner ring
using (SolidBrush b = new SolidBrush(this._InnerColor))
{
e.Graphics.FillEllipse(b, InnerRect);
}
//Draw percentage
if (ShowPercentage)
{
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
using (SolidBrush b = new SolidBrush(this.ForeColor))
{
e.Graphics.DrawString(Convert.ToInt32(Value).ToString() + "%", this.Font, b, InnerRect, sf);
}
}
}
}
#endregion
}
The result:
I've made a custom control and I want to add a click event so when the user clicks anywhere on the control it will return the position of where the user has clicked on the control. For example if the user clicks in the middle of the bar it would essentially return me enough information for me to calculate 50% and that the user has clicked in the middle.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace CustomRangeBar
{
public partial class RangeBar : UserControl
{
public RangeBar()
{
InitializeComponent();
label1.ForeColor = Color.Black;
this.ForeColor = SystemColors.Highlight; // set the default color the rangeBar
this.Click += new EventHandler(RangeBar_Click);
}
protected float percent = 0.0f; // Protected because we don't want this to be accessed from the outside
// Create a Value property for the rangeBar
public float Value
{
get
{
return percent;
}
set
{
// Maintain the value between 0 and 100
if (value < 0) value = 0;
else if (value > 100) value = 100;
percent = value;
label1.Text = value.ToString();
//redraw the rangeBar every time the value changes
this.Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Brush b = new SolidBrush(this.ForeColor); //create brush that will draw the background of the range bar
// create a linear gradient that will be drawn over the background. FromArgb means you can use the Alpha value which is the transparency
LinearGradientBrush lb = new LinearGradientBrush(new Rectangle(0, 0, this.Width, this.Height), Color.FromArgb(255, Color.White), Color.FromArgb(50, Color.White), LinearGradientMode.Vertical);
// calculate how much has the rangeBar to be filled for 'x' %
int width = (int)((percent / 100) * this.Width);
e.Graphics.FillRectangle(b, 0, 0, width, this.Height);
e.Graphics.FillRectangle(lb, 0, 0, width, this.Height);
b.Dispose(); lb.Dispose();
}
private void RangeBar_SizeChanged(object sender, EventArgs e)
{
// maintain the label in the center of the rangeBar
label1.Location = new Point(this.Width / 2 - 21 / 2 - 4, this.Height / 2 - 15 / 2);
}
}
}
public void RangeBar_Click(object obj, EventArgs ea)
{
// This get executed if the pictureBox gets clicked
label1.text = "Increment 1";
}
OnClick is not a good function to override or subscribe to because it does not tell you the position where the click happened which is what you are looking for.
What you want is OnMouseClick which includes the x,y of the click point.
protected override void OnMouseClick(MouseEventArgs e)
{
int x = e.X;
int y = e.Y;
//Do your calculation here.
}
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.