Translucent circle with text
I am working on a project wherein I need to add a Circle with text in the middle. I am using the code below. But my problem is the circle is too small, when I resize it, it overlaps other control. I want to draw the circle same width as the square or how will make the back ground as transparent?
protected override void OnPaint(PaintEventArgs e)
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
using (Graphics graphics = Graphics.FromImage(bitmap))
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);
using (SolidBrush brush = new SolidBrush(this._FillColor))
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
c# winforms transparency
|
show 4 more comments
I am working on a project wherein I need to add a Circle with text in the middle. I am using the code below. But my problem is the circle is too small, when I resize it, it overlaps other control. I want to draw the circle same width as the square or how will make the back ground as transparent?
protected override void OnPaint(PaintEventArgs e)
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
using (Graphics graphics = Graphics.FromImage(bitmap))
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);
using (SolidBrush brush = new SolidBrush(this._FillColor))
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
c# winforms transparency
Seems like you're making the circle too small. Have you tried increasing values ofgraphics.FillEllipse
?
– Shocky
Jul 18 at 8:05
1
Your circle is exactly as big as I expect it to be based on your code. Your problem is that you're drawing it at 18, 18 with the approximate size 41x41, but you want it to be 0, 0 with approximate size 77x77. It seems to me that all you need isgraphics.FillEllipse(brush, e.ClipRectangle);
without all the extraBitmap
stuff, etc.
– John
Jul 18 at 8:13
@john Thanks, that works fine. But i did not remove the Bitmap thing, when i remove that, the circle is not showing.
– Zhyke
Jul 18 at 8:27
I meant that why don't you just usee.Graphics
rather than creating a bitmap, creating an instance ofGraphics
for the bitmap, drawing everything onto that before finally usinge.Graphics
to draw it to the control?
– John
Jul 18 at 8:31
1
In winforms there is no such thing as 'a circle'. There are only controls with surfaces consisting of pixels. And bitmaps.We have no idea what you want to do. So there really is not advice what to do best. To place a text centered in a bitmap you should: use TextRenderer.DrawText not Graphics.DrawString b) draw into a rectangle c) use centered StringFormat.
– TaW
Jul 18 at 8:33
|
show 4 more comments
I am working on a project wherein I need to add a Circle with text in the middle. I am using the code below. But my problem is the circle is too small, when I resize it, it overlaps other control. I want to draw the circle same width as the square or how will make the back ground as transparent?
protected override void OnPaint(PaintEventArgs e)
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
using (Graphics graphics = Graphics.FromImage(bitmap))
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);
using (SolidBrush brush = new SolidBrush(this._FillColor))
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
c# winforms transparency
I am working on a project wherein I need to add a Circle with text in the middle. I am using the code below. But my problem is the circle is too small, when I resize it, it overlaps other control. I want to draw the circle same width as the square or how will make the back ground as transparent?
protected override void OnPaint(PaintEventArgs e)
base.OnPaint(e);
using (Bitmap bitmap = new Bitmap(this.Width, this.Height))
using (Graphics graphics = Graphics.FromImage(bitmap))
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.Clear(this.BackColor);
using (SolidBrush brush = new SolidBrush(this._FillColor))
graphics.FillEllipse(brush, 0x18 - 6, 0x18 - 6, (this.Width - 0x30) + 12, (this.Height - 0x30) + 12);
Brush FontColor = new SolidBrush(this.ForeColor);
SizeF MS = graphics.MeasureString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font);
graphics.DrawString(Convert.ToString(Convert.ToInt32((100 / _Maximum) * _Value)), Font, FontColor, Convert.ToInt32((Width / 2 - MS.Width / 2) + 2), Convert.ToInt32((Height / 2 - MS.Height / 2) + 3));
bitmap.MakeTransparent(this.BackColor);
e.Graphics.DrawImage(bitmap, 0, 0);
graphics.Dispose();
bitmap.Dispose();
c# winforms transparency
c# winforms transparency
edited Nov 11 at 5:42
Jimi
6,56931533
6,56931533
asked Jul 18 at 8:03
Zhyke
209110
209110
Seems like you're making the circle too small. Have you tried increasing values ofgraphics.FillEllipse
?
– Shocky
Jul 18 at 8:05
1
Your circle is exactly as big as I expect it to be based on your code. Your problem is that you're drawing it at 18, 18 with the approximate size 41x41, but you want it to be 0, 0 with approximate size 77x77. It seems to me that all you need isgraphics.FillEllipse(brush, e.ClipRectangle);
without all the extraBitmap
stuff, etc.
– John
Jul 18 at 8:13
@john Thanks, that works fine. But i did not remove the Bitmap thing, when i remove that, the circle is not showing.
– Zhyke
Jul 18 at 8:27
I meant that why don't you just usee.Graphics
rather than creating a bitmap, creating an instance ofGraphics
for the bitmap, drawing everything onto that before finally usinge.Graphics
to draw it to the control?
– John
Jul 18 at 8:31
1
In winforms there is no such thing as 'a circle'. There are only controls with surfaces consisting of pixels. And bitmaps.We have no idea what you want to do. So there really is not advice what to do best. To place a text centered in a bitmap you should: use TextRenderer.DrawText not Graphics.DrawString b) draw into a rectangle c) use centered StringFormat.
– TaW
Jul 18 at 8:33
|
show 4 more comments
Seems like you're making the circle too small. Have you tried increasing values ofgraphics.FillEllipse
?
– Shocky
Jul 18 at 8:05
1
Your circle is exactly as big as I expect it to be based on your code. Your problem is that you're drawing it at 18, 18 with the approximate size 41x41, but you want it to be 0, 0 with approximate size 77x77. It seems to me that all you need isgraphics.FillEllipse(brush, e.ClipRectangle);
without all the extraBitmap
stuff, etc.
– John
Jul 18 at 8:13
@john Thanks, that works fine. But i did not remove the Bitmap thing, when i remove that, the circle is not showing.
– Zhyke
Jul 18 at 8:27
I meant that why don't you just usee.Graphics
rather than creating a bitmap, creating an instance ofGraphics
for the bitmap, drawing everything onto that before finally usinge.Graphics
to draw it to the control?
– John
Jul 18 at 8:31
1
In winforms there is no such thing as 'a circle'. There are only controls with surfaces consisting of pixels. And bitmaps.We have no idea what you want to do. So there really is not advice what to do best. To place a text centered in a bitmap you should: use TextRenderer.DrawText not Graphics.DrawString b) draw into a rectangle c) use centered StringFormat.
– TaW
Jul 18 at 8:33
Seems like you're making the circle too small. Have you tried increasing values of
graphics.FillEllipse
?– Shocky
Jul 18 at 8:05
Seems like you're making the circle too small. Have you tried increasing values of
graphics.FillEllipse
?– Shocky
Jul 18 at 8:05
1
1
Your circle is exactly as big as I expect it to be based on your code. Your problem is that you're drawing it at 18, 18 with the approximate size 41x41, but you want it to be 0, 0 with approximate size 77x77. It seems to me that all you need is
graphics.FillEllipse(brush, e.ClipRectangle);
without all the extra Bitmap
stuff, etc.– John
Jul 18 at 8:13
Your circle is exactly as big as I expect it to be based on your code. Your problem is that you're drawing it at 18, 18 with the approximate size 41x41, but you want it to be 0, 0 with approximate size 77x77. It seems to me that all you need is
graphics.FillEllipse(brush, e.ClipRectangle);
without all the extra Bitmap
stuff, etc.– John
Jul 18 at 8:13
@john Thanks, that works fine. But i did not remove the Bitmap thing, when i remove that, the circle is not showing.
– Zhyke
Jul 18 at 8:27
@john Thanks, that works fine. But i did not remove the Bitmap thing, when i remove that, the circle is not showing.
– Zhyke
Jul 18 at 8:27
I meant that why don't you just use
e.Graphics
rather than creating a bitmap, creating an instance of Graphics
for the bitmap, drawing everything onto that before finally using e.Graphics
to draw it to the control?– John
Jul 18 at 8:31
I meant that why don't you just use
e.Graphics
rather than creating a bitmap, creating an instance of Graphics
for the bitmap, drawing everything onto that before finally using e.Graphics
to draw it to the control?– John
Jul 18 at 8:31
1
1
In winforms there is no such thing as 'a circle'. There are only controls with surfaces consisting of pixels. And bitmaps.We have no idea what you want to do. So there really is not advice what to do best. To place a text centered in a bitmap you should: use TextRenderer.DrawText not Graphics.DrawString b) draw into a rectangle c) use centered StringFormat.
– TaW
Jul 18 at 8:33
In winforms there is no such thing as 'a circle'. There are only controls with surfaces consisting of pixels. And bitmaps.We have no idea what you want to do. So there really is not advice what to do best. To place a text centered in a bitmap you should: use TextRenderer.DrawText not Graphics.DrawString b) draw into a rectangle c) use centered StringFormat.
– TaW
Jul 18 at 8:33
|
show 4 more comments
1 Answer
1
active
oldest
votes
This is a Custom Control derived from a standard Label
, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity
: The level of opacity of the control BackGround
[0, 255]
InnerPadding
: The distance between the inner rectangle, which defines the circle bounds and the control bounds.FontPadding
: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behaviour, adding these ControlStyles:
ControlStyles.Opaque
prevents the painting of the control BackGround
, so it's not managed by the System.ControlStyles.SupportsTransparentBackColor
the control accepts Alpha values for it's BackGround
color.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox.
Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Apparently, ScreenToGif
ignores the Pixel change on full opacity.
In its opinion nothing changes, so it optimizes
it showing nothing.
Note:
I didn't use TextRenderer here because of its padding. It's harder to control in this context: the vertical center position needs to be adjusted and it doesn't provide any quality enhancements.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;
[DesignerCategory("Code")]
class RoundCenterLabel : Label, INotifyPropertyChanged
internal const int WS_EX_TRANSPARENT = 0x00000020;
internal Font m_CustomFont = null;
internal Color m_BackGroundColor;
internal int m_InnerPadding = 0;
internal int m_FontPadding = 25;
internal int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
this.SetStyle(ControlStyles.Opaque
private void NotifyPropertyChanged(string PropertyName)
this.Invalidate();
this.FindForm()?.Refresh();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
public new Font Font
get => this.m_CustomFont;
set this.m_CustomFont = value;
FontAdapter(value, this.DeviceDpi);
NotifyPropertyChanged(nameof(this.Font));
public override string Text
get => base.Text;
set base.Text = value;
NotifyPropertyChanged(nameof(this.Text));
public int InnerPadding
get => this.m_InnerPadding;
set this.m_InnerPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.InnerPadding));
public int FontPadding
get => this.m_FontPadding;
set this.m_FontPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.FontPadding));
public int Opacity
get => this.m_Opacity;
set this.m_Opacity = CheckValue(value, 0, 255);
UpdateBackColor(this.m_BackGroundColor);
NotifyPropertyChanged(nameof(this.Opacity));
public override Color BackColor
get => this.m_BackGroundColor;
set UpdateBackColor(value);
NotifyPropertyChanged(nameof(this.BackColor));
protected override void OnLayout(LayoutEventArgs evt)
base.OnLayout(evt);
base.AutoSize = false;
protected override void OnPaint(PaintEventArgs e)
StringFormat format = new StringFormat(StringFormatFlags.LineLimit, CultureInfo.CurrentUICulture.LCID)
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (SolidBrush CircleBrush = new SolidBrush(this.m_BackGroundColor))
using (SolidBrush ForeBrush = new SolidBrush(this.ForeColor))
this.FontAdapter(this.m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(CircleBrush, rect);
e.Graphics.DrawString(this.Text, this.m_CustomFont, ForeBrush, rect, format);
private RectangleF InnerRectangle()
Tuple<decimal, decimal> refSize = GetMinMax(this.ClientRectangle.Height, this.ClientRectangle.Width);
SizeF size = new SizeF((float)refSize.Item1 - (this.m_InnerPadding / 2),
(float)refSize.Item1 - (this.m_InnerPadding / 2));
PointF position = new PointF((this.ClientRectangle.Width - size.Width) / 2,
(this.ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
private void FontAdapter(Font font, float Dpi)
RectangleF rect = InnerRectangle();
float FontSize = CheckValue((int)(rect.Height - this.m_FontPadding), 6,
(int)(rect.Height - this.m_FontPadding)) / (Dpi / 72.0F);
using (Font customfont = new Font(font.FontFamily, FontSize, font.Style, GraphicsUnit.Pixel))
this.m_CustomFont = (Font)customfont.Clone();
private void UpdateBackColor(Color color)
this.m_BackGroundColor = Color.FromArgb(this.m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = this.m_BackGroundColor;
private int CheckValue(int Value, int Min, int Max)
return (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private Tuple<decimal, decimal> GetMinMax(ValueType Value1, ValueType Value2)
protected override CreateParams CreateParams
get
= WS_EX_TRANSPARENT;
return parameters;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51396681%2ftranslucent-circle-with-text%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is a Custom Control derived from a standard Label
, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity
: The level of opacity of the control BackGround
[0, 255]
InnerPadding
: The distance between the inner rectangle, which defines the circle bounds and the control bounds.FontPadding
: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behaviour, adding these ControlStyles:
ControlStyles.Opaque
prevents the painting of the control BackGround
, so it's not managed by the System.ControlStyles.SupportsTransparentBackColor
the control accepts Alpha values for it's BackGround
color.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox.
Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Apparently, ScreenToGif
ignores the Pixel change on full opacity.
In its opinion nothing changes, so it optimizes
it showing nothing.
Note:
I didn't use TextRenderer here because of its padding. It's harder to control in this context: the vertical center position needs to be adjusted and it doesn't provide any quality enhancements.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;
[DesignerCategory("Code")]
class RoundCenterLabel : Label, INotifyPropertyChanged
internal const int WS_EX_TRANSPARENT = 0x00000020;
internal Font m_CustomFont = null;
internal Color m_BackGroundColor;
internal int m_InnerPadding = 0;
internal int m_FontPadding = 25;
internal int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
this.SetStyle(ControlStyles.Opaque
private void NotifyPropertyChanged(string PropertyName)
this.Invalidate();
this.FindForm()?.Refresh();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
public new Font Font
get => this.m_CustomFont;
set this.m_CustomFont = value;
FontAdapter(value, this.DeviceDpi);
NotifyPropertyChanged(nameof(this.Font));
public override string Text
get => base.Text;
set base.Text = value;
NotifyPropertyChanged(nameof(this.Text));
public int InnerPadding
get => this.m_InnerPadding;
set this.m_InnerPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.InnerPadding));
public int FontPadding
get => this.m_FontPadding;
set this.m_FontPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.FontPadding));
public int Opacity
get => this.m_Opacity;
set this.m_Opacity = CheckValue(value, 0, 255);
UpdateBackColor(this.m_BackGroundColor);
NotifyPropertyChanged(nameof(this.Opacity));
public override Color BackColor
get => this.m_BackGroundColor;
set UpdateBackColor(value);
NotifyPropertyChanged(nameof(this.BackColor));
protected override void OnLayout(LayoutEventArgs evt)
base.OnLayout(evt);
base.AutoSize = false;
protected override void OnPaint(PaintEventArgs e)
StringFormat format = new StringFormat(StringFormatFlags.LineLimit, CultureInfo.CurrentUICulture.LCID)
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (SolidBrush CircleBrush = new SolidBrush(this.m_BackGroundColor))
using (SolidBrush ForeBrush = new SolidBrush(this.ForeColor))
this.FontAdapter(this.m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(CircleBrush, rect);
e.Graphics.DrawString(this.Text, this.m_CustomFont, ForeBrush, rect, format);
private RectangleF InnerRectangle()
Tuple<decimal, decimal> refSize = GetMinMax(this.ClientRectangle.Height, this.ClientRectangle.Width);
SizeF size = new SizeF((float)refSize.Item1 - (this.m_InnerPadding / 2),
(float)refSize.Item1 - (this.m_InnerPadding / 2));
PointF position = new PointF((this.ClientRectangle.Width - size.Width) / 2,
(this.ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
private void FontAdapter(Font font, float Dpi)
RectangleF rect = InnerRectangle();
float FontSize = CheckValue((int)(rect.Height - this.m_FontPadding), 6,
(int)(rect.Height - this.m_FontPadding)) / (Dpi / 72.0F);
using (Font customfont = new Font(font.FontFamily, FontSize, font.Style, GraphicsUnit.Pixel))
this.m_CustomFont = (Font)customfont.Clone();
private void UpdateBackColor(Color color)
this.m_BackGroundColor = Color.FromArgb(this.m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = this.m_BackGroundColor;
private int CheckValue(int Value, int Min, int Max)
return (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private Tuple<decimal, decimal> GetMinMax(ValueType Value1, ValueType Value2)
protected override CreateParams CreateParams
get
= WS_EX_TRANSPARENT;
return parameters;
add a comment |
This is a Custom Control derived from a standard Label
, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity
: The level of opacity of the control BackGround
[0, 255]
InnerPadding
: The distance between the inner rectangle, which defines the circle bounds and the control bounds.FontPadding
: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behaviour, adding these ControlStyles:
ControlStyles.Opaque
prevents the painting of the control BackGround
, so it's not managed by the System.ControlStyles.SupportsTransparentBackColor
the control accepts Alpha values for it's BackGround
color.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox.
Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Apparently, ScreenToGif
ignores the Pixel change on full opacity.
In its opinion nothing changes, so it optimizes
it showing nothing.
Note:
I didn't use TextRenderer here because of its padding. It's harder to control in this context: the vertical center position needs to be adjusted and it doesn't provide any quality enhancements.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;
[DesignerCategory("Code")]
class RoundCenterLabel : Label, INotifyPropertyChanged
internal const int WS_EX_TRANSPARENT = 0x00000020;
internal Font m_CustomFont = null;
internal Color m_BackGroundColor;
internal int m_InnerPadding = 0;
internal int m_FontPadding = 25;
internal int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
this.SetStyle(ControlStyles.Opaque
private void NotifyPropertyChanged(string PropertyName)
this.Invalidate();
this.FindForm()?.Refresh();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
public new Font Font
get => this.m_CustomFont;
set this.m_CustomFont = value;
FontAdapter(value, this.DeviceDpi);
NotifyPropertyChanged(nameof(this.Font));
public override string Text
get => base.Text;
set base.Text = value;
NotifyPropertyChanged(nameof(this.Text));
public int InnerPadding
get => this.m_InnerPadding;
set this.m_InnerPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.InnerPadding));
public int FontPadding
get => this.m_FontPadding;
set this.m_FontPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.FontPadding));
public int Opacity
get => this.m_Opacity;
set this.m_Opacity = CheckValue(value, 0, 255);
UpdateBackColor(this.m_BackGroundColor);
NotifyPropertyChanged(nameof(this.Opacity));
public override Color BackColor
get => this.m_BackGroundColor;
set UpdateBackColor(value);
NotifyPropertyChanged(nameof(this.BackColor));
protected override void OnLayout(LayoutEventArgs evt)
base.OnLayout(evt);
base.AutoSize = false;
protected override void OnPaint(PaintEventArgs e)
StringFormat format = new StringFormat(StringFormatFlags.LineLimit, CultureInfo.CurrentUICulture.LCID)
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (SolidBrush CircleBrush = new SolidBrush(this.m_BackGroundColor))
using (SolidBrush ForeBrush = new SolidBrush(this.ForeColor))
this.FontAdapter(this.m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(CircleBrush, rect);
e.Graphics.DrawString(this.Text, this.m_CustomFont, ForeBrush, rect, format);
private RectangleF InnerRectangle()
Tuple<decimal, decimal> refSize = GetMinMax(this.ClientRectangle.Height, this.ClientRectangle.Width);
SizeF size = new SizeF((float)refSize.Item1 - (this.m_InnerPadding / 2),
(float)refSize.Item1 - (this.m_InnerPadding / 2));
PointF position = new PointF((this.ClientRectangle.Width - size.Width) / 2,
(this.ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
private void FontAdapter(Font font, float Dpi)
RectangleF rect = InnerRectangle();
float FontSize = CheckValue((int)(rect.Height - this.m_FontPadding), 6,
(int)(rect.Height - this.m_FontPadding)) / (Dpi / 72.0F);
using (Font customfont = new Font(font.FontFamily, FontSize, font.Style, GraphicsUnit.Pixel))
this.m_CustomFont = (Font)customfont.Clone();
private void UpdateBackColor(Color color)
this.m_BackGroundColor = Color.FromArgb(this.m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = this.m_BackGroundColor;
private int CheckValue(int Value, int Min, int Max)
return (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private Tuple<decimal, decimal> GetMinMax(ValueType Value1, ValueType Value2)
protected override CreateParams CreateParams
get
= WS_EX_TRANSPARENT;
return parameters;
add a comment |
This is a Custom Control derived from a standard Label
, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity
: The level of opacity of the control BackGround
[0, 255]
InnerPadding
: The distance between the inner rectangle, which defines the circle bounds and the control bounds.FontPadding
: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behaviour, adding these ControlStyles:
ControlStyles.Opaque
prevents the painting of the control BackGround
, so it's not managed by the System.ControlStyles.SupportsTransparentBackColor
the control accepts Alpha values for it's BackGround
color.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox.
Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Apparently, ScreenToGif
ignores the Pixel change on full opacity.
In its opinion nothing changes, so it optimizes
it showing nothing.
Note:
I didn't use TextRenderer here because of its padding. It's harder to control in this context: the vertical center position needs to be adjusted and it doesn't provide any quality enhancements.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;
[DesignerCategory("Code")]
class RoundCenterLabel : Label, INotifyPropertyChanged
internal const int WS_EX_TRANSPARENT = 0x00000020;
internal Font m_CustomFont = null;
internal Color m_BackGroundColor;
internal int m_InnerPadding = 0;
internal int m_FontPadding = 25;
internal int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
this.SetStyle(ControlStyles.Opaque
private void NotifyPropertyChanged(string PropertyName)
this.Invalidate();
this.FindForm()?.Refresh();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
public new Font Font
get => this.m_CustomFont;
set this.m_CustomFont = value;
FontAdapter(value, this.DeviceDpi);
NotifyPropertyChanged(nameof(this.Font));
public override string Text
get => base.Text;
set base.Text = value;
NotifyPropertyChanged(nameof(this.Text));
public int InnerPadding
get => this.m_InnerPadding;
set this.m_InnerPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.InnerPadding));
public int FontPadding
get => this.m_FontPadding;
set this.m_FontPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.FontPadding));
public int Opacity
get => this.m_Opacity;
set this.m_Opacity = CheckValue(value, 0, 255);
UpdateBackColor(this.m_BackGroundColor);
NotifyPropertyChanged(nameof(this.Opacity));
public override Color BackColor
get => this.m_BackGroundColor;
set UpdateBackColor(value);
NotifyPropertyChanged(nameof(this.BackColor));
protected override void OnLayout(LayoutEventArgs evt)
base.OnLayout(evt);
base.AutoSize = false;
protected override void OnPaint(PaintEventArgs e)
StringFormat format = new StringFormat(StringFormatFlags.LineLimit, CultureInfo.CurrentUICulture.LCID)
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (SolidBrush CircleBrush = new SolidBrush(this.m_BackGroundColor))
using (SolidBrush ForeBrush = new SolidBrush(this.ForeColor))
this.FontAdapter(this.m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(CircleBrush, rect);
e.Graphics.DrawString(this.Text, this.m_CustomFont, ForeBrush, rect, format);
private RectangleF InnerRectangle()
Tuple<decimal, decimal> refSize = GetMinMax(this.ClientRectangle.Height, this.ClientRectangle.Width);
SizeF size = new SizeF((float)refSize.Item1 - (this.m_InnerPadding / 2),
(float)refSize.Item1 - (this.m_InnerPadding / 2));
PointF position = new PointF((this.ClientRectangle.Width - size.Width) / 2,
(this.ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
private void FontAdapter(Font font, float Dpi)
RectangleF rect = InnerRectangle();
float FontSize = CheckValue((int)(rect.Height - this.m_FontPadding), 6,
(int)(rect.Height - this.m_FontPadding)) / (Dpi / 72.0F);
using (Font customfont = new Font(font.FontFamily, FontSize, font.Style, GraphicsUnit.Pixel))
this.m_CustomFont = (Font)customfont.Clone();
private void UpdateBackColor(Color color)
this.m_BackGroundColor = Color.FromArgb(this.m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = this.m_BackGroundColor;
private int CheckValue(int Value, int Min, int Max)
return (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private Tuple<decimal, decimal> GetMinMax(ValueType Value1, ValueType Value2)
protected override CreateParams CreateParams
get
= WS_EX_TRANSPARENT;
return parameters;
This is a Custom Control derived from a standard Label
, which can be made translucent.
The interface is a colored circle which can contain a couple of numbers.
The Control exposes these custom properties:
Opacity
: The level of opacity of the control BackGround
[0, 255]
InnerPadding
: The distance between the inner rectangle, which defines the circle bounds and the control bounds.FontPadding
: The distance between the Text and the Inner rectangle.
Transparency is obtained overriding CreateParams, then setting ExStyle |= WS_EX_TRANSPARENT;
The Control.SetStyle() method is used to modify the control behaviour, adding these ControlStyles:
ControlStyles.Opaque
prevents the painting of the control BackGround
, so it's not managed by the System.ControlStyles.SupportsTransparentBackColor
the control accepts Alpha values for it's BackGround
color.
To see it at work, create a new Class file, substitute all the code inside with this code preserving the NameSpace and build the Project/Solution.
The new Custom Control will appear in the ToolBox.
Drop it on a Form. Modify its custom properties as needed.
A visual representation of the control:
Apparently, ScreenToGif
ignores the Pixel change on full opacity.
In its opinion nothing changes, so it optimizes
it showing nothing.
Note:
I didn't use TextRenderer here because of its padding. It's harder to control in this context: the vertical center position needs to be adjusted and it doesn't provide any quality enhancements.
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;
[DesignerCategory("Code")]
class RoundCenterLabel : Label, INotifyPropertyChanged
internal const int WS_EX_TRANSPARENT = 0x00000020;
internal Font m_CustomFont = null;
internal Color m_BackGroundColor;
internal int m_InnerPadding = 0;
internal int m_FontPadding = 25;
internal int m_Opacity = 128;
public event PropertyChangedEventHandler PropertyChanged;
public RoundCenterLabel() => InitializeComponent();
private void InitializeComponent()
this.SetStyle(ControlStyles.Opaque
private void NotifyPropertyChanged(string PropertyName)
this.Invalidate();
this.FindForm()?.Refresh();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
public new Font Font
get => this.m_CustomFont;
set this.m_CustomFont = value;
FontAdapter(value, this.DeviceDpi);
NotifyPropertyChanged(nameof(this.Font));
public override string Text
get => base.Text;
set base.Text = value;
NotifyPropertyChanged(nameof(this.Text));
public int InnerPadding
get => this.m_InnerPadding;
set this.m_InnerPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.InnerPadding));
public int FontPadding
get => this.m_FontPadding;
set this.m_FontPadding = CheckValue(value, 0, this.ClientRectangle.Height - 10);
NotifyPropertyChanged(nameof(this.FontPadding));
public int Opacity
get => this.m_Opacity;
set this.m_Opacity = CheckValue(value, 0, 255);
UpdateBackColor(this.m_BackGroundColor);
NotifyPropertyChanged(nameof(this.Opacity));
public override Color BackColor
get => this.m_BackGroundColor;
set UpdateBackColor(value);
NotifyPropertyChanged(nameof(this.BackColor));
protected override void OnLayout(LayoutEventArgs evt)
base.OnLayout(evt);
base.AutoSize = false;
protected override void OnPaint(PaintEventArgs e)
StringFormat format = new StringFormat(StringFormatFlags.LineLimit, CultureInfo.CurrentUICulture.LCID)
LineAlignment = StringAlignment.Center,
Alignment = StringAlignment.Center
;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
using (SolidBrush CircleBrush = new SolidBrush(this.m_BackGroundColor))
using (SolidBrush ForeBrush = new SolidBrush(this.ForeColor))
this.FontAdapter(this.m_CustomFont, e.Graphics.DpiY);
RectangleF rect = InnerRectangle();
e.Graphics.FillEllipse(CircleBrush, rect);
e.Graphics.DrawString(this.Text, this.m_CustomFont, ForeBrush, rect, format);
private RectangleF InnerRectangle()
Tuple<decimal, decimal> refSize = GetMinMax(this.ClientRectangle.Height, this.ClientRectangle.Width);
SizeF size = new SizeF((float)refSize.Item1 - (this.m_InnerPadding / 2),
(float)refSize.Item1 - (this.m_InnerPadding / 2));
PointF position = new PointF((this.ClientRectangle.Width - size.Width) / 2,
(this.ClientRectangle.Height - size.Height) / 2);
return new RectangleF(position, size);
private void FontAdapter(Font font, float Dpi)
RectangleF rect = InnerRectangle();
float FontSize = CheckValue((int)(rect.Height - this.m_FontPadding), 6,
(int)(rect.Height - this.m_FontPadding)) / (Dpi / 72.0F);
using (Font customfont = new Font(font.FontFamily, FontSize, font.Style, GraphicsUnit.Pixel))
this.m_CustomFont = (Font)customfont.Clone();
private void UpdateBackColor(Color color)
this.m_BackGroundColor = Color.FromArgb(this.m_Opacity, Color.FromArgb(color.R, color.G, color.B));
base.BackColor = this.m_BackGroundColor;
private int CheckValue(int Value, int Min, int Max)
return (Value < Min) ? Min : ((Value > Max) ? Max : Value);
private Tuple<decimal, decimal> GetMinMax(ValueType Value1, ValueType Value2)
protected override CreateParams CreateParams
get
= WS_EX_TRANSPARENT;
return parameters;
edited Nov 23 at 16:09
answered Jul 20 at 5:50
Jimi
6,56931533
6,56931533
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51396681%2ftranslucent-circle-with-text%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Seems like you're making the circle too small. Have you tried increasing values of
graphics.FillEllipse
?– Shocky
Jul 18 at 8:05
1
Your circle is exactly as big as I expect it to be based on your code. Your problem is that you're drawing it at 18, 18 with the approximate size 41x41, but you want it to be 0, 0 with approximate size 77x77. It seems to me that all you need is
graphics.FillEllipse(brush, e.ClipRectangle);
without all the extraBitmap
stuff, etc.– John
Jul 18 at 8:13
@john Thanks, that works fine. But i did not remove the Bitmap thing, when i remove that, the circle is not showing.
– Zhyke
Jul 18 at 8:27
I meant that why don't you just use
e.Graphics
rather than creating a bitmap, creating an instance ofGraphics
for the bitmap, drawing everything onto that before finally usinge.Graphics
to draw it to the control?– John
Jul 18 at 8:31
1
In winforms there is no such thing as 'a circle'. There are only controls with surfaces consisting of pixels. And bitmaps.We have no idea what you want to do. So there really is not advice what to do best. To place a text centered in a bitmap you should: use TextRenderer.DrawText not Graphics.DrawString b) draw into a rectangle c) use centered StringFormat.
– TaW
Jul 18 at 8:33