I'm trying to build custom user control that will display Font Awesome Glyphs inside winforms Button.
I found GitHub repo with similar control, but I would like to use Button as base of my control.
I'm able to show glyph, but I can't align it correctly:
Green dotted line shows button size, blue lines indicates center of control and red lines show rectangle that graphics.MeasureString
is returning.
My OnPaint
method looks like this:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var graphics = e.Graphics;
// Set best quality
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
if(!DesignMode)
{
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
}
var letter = char.ConvertFromUtf32((int)_icon);
Brush b;
if (!Enabled)
{
b = Brushes.LightGray;
}
else if (_mouseDown)
{
b = new SolidBrush(_clickColor);
}
else if (_mouseOver)
{
b = new SolidBrush(_hoverColor);
}
else
{
b = new SolidBrush(ForeColor);
}
SizeF s = graphics.MeasureString(letter, new Font(Fonts.Families[0], _iconSize, GraphicsUnit.Point), Width);
float w = s.Width;
float h = s.Height;
// center icon
float left = Padding.Left + (Width - w)/2;
float top = Padding.Top + (Height - h)/2;
if (DesignMode)
{
graphics.DrawRectangle(Pens.Red, top, left, w, h);
}
graphics.DrawString(letter, new Font(Fonts.Families[0], _iconSize, GraphicsUnit.Point), b, new PointF(left, top));
if (DesignMode)
{
var pen = new Pen(_hoverColor, 1) { DashStyle = DashStyle.Dash, Alignment = PenAlignment.Inset };
graphics.DrawRectangle(pen, Padding.Left, Padding.Top, Width - Padding.Left - Padding.Right - 1, Height - Padding.Top - Padding.Bottom - 1);
graphics.DrawLine(Pens.Blue, Padding.Left, Padding.Top, Width - Padding.Left, Height - Padding.Top);
graphics.DrawLine(Pens.Blue, Width - Padding.Left, Padding.Top, Padding.Left, Height - Padding.Top);
}
}
I tried using solution from this question but without any luck.
How can I draw single character (glyph) in my control exact center (center of control and center of glyph should align)
Here is code for my control:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MyControls
{
class FontButton:Button
{
#region Public
public FontButton()
{
base.FlatStyle = FlatStyle.Flat;
base.FlatAppearance.BorderSize = 0;
base.FlatAppearance.MouseOverBackColor = Color.Transparent;
base.FlatAppearance.MouseDownBackColor = Color.Transparent;
base.Text = "";
base.MinimumSize = new Size(32,32);
Size = new Size(32,32);
_hoverColor = Color.FromArgb(144, 188, 0);
_clickColor = Color.Green;
_icon=IconType.Android;
_iconSize = 40;
}
private int _iconSize;
[DefaultValue(typeof(int), "40"), Category("Appearance"), Description("Icon size in points")]
public int IconSize
{
get { return _iconSize; }
set
{
_iconSize = value;
Invalidate();
}
}
private Color _hoverColor;
[DefaultValue(typeof(Color), "144, 188, 0"), Category("Appearance"), Description("Color when mouse over")]
public Color HoverColor
{
get { return _hoverColor; }
set
{
_hoverColor = value;
Invalidate();
}
}
private Color _clickColor;
[DefaultValue(typeof(Color), "Green"), Category("Appearance"), Description("Color when mouse click")]
public Color ClickColor
{
get { return _clickColor; }
set
{
_clickColor = value;
Invalidate();
}
}
private IconType _icon;
[DefaultValue(typeof(IconType), "Android"), Category("Appearance"), Description("Icon")]
public IconType Icon
{
get { return _icon; }
set
{
_icon = value;
Invalidate();
}
}
#endregion
#region Static
static FontButton()
{
InitialiseFont();
}
#region NATIVE
[DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(byte[] pbFont, int cbFont, IntPtr pdv, out uint pcFonts);
#endregion
private static readonly PrivateFontCollection Fonts = new PrivateFontCollection();
private static void InitialiseFont()
{
try
{
byte[] fontdata = ImageButtonTest.Properties.Resources.fontawesome_webfont;
IntPtr ptrFont = Marshal.AllocCoTaskMem(fontdata.Length);
uint cFonts;
AddFontMemResourceEx(fontdata, fontdata.Length, IntPtr.Zero, out cFonts);
Marshal.Copy(fontdata, 0, ptrFont, fontdata.Length);
Fonts.AddMemoryFont(ptrFont, fontdata.Length);
Marshal.FreeCoTaskMem(ptrFont);
}
catch (Exception)
{
Debug.WriteLine("Error");
throw;
}
}
#endregion
#region Overrides
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var graphics = e.Graphics;
// Set best quality
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
if(!DesignMode)
{
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
}
var letter = char.ConvertFromUtf32((int)_icon);//char.ConvertFromUtf32(0xf190);
Brush b;
if (!Enabled)
{
b = Brushes.LightGray;
}
else if (_mouseDown)
{
b = new SolidBrush(_clickColor);
}
else if (_mouseOver)
{
b = new SolidBrush(_hoverColor);
}
else
{
b = new SolidBrush(ForeColor);
}
SizeF s = graphics.MeasureString(letter, new Font(Fonts.Families[0], _iconSize, GraphicsUnit.Point), Width);
//SizeF s = TextRenderer.MeasureText(letter, new Font(Fonts.Families[0], _iconSize, GraphicsUnit.Point), new Size(20, 20), TextFormatFlags.NoPadding);
//Debug.WriteLine(stringSize);
//Debug.WriteLine(s);
float w = s.Width;
float h = s.Height;
// center icon
float left = Padding.Left + (Width - w)/2;
float top = Padding.Top + (Height - h)/2;
if (DesignMode)
{
graphics.DrawRectangle(Pens.Red, top, left, w, h);
}
graphics.DrawString(letter, new Font(Fonts.Families[0], _iconSize, GraphicsUnit.Point), b, new PointF(left, top));
if (DesignMode)//Process.GetCurrentProcess().ProcessName == "devenv")
{
var pen = new Pen(_hoverColor, 1) { DashStyle = DashStyle.Dash, Alignment = PenAlignment.Inset };
graphics.DrawRectangle(pen, Padding.Left, Padding.Top, Width - Padding.Left - Padding.Right - 1, Height - Padding.Top - Padding.Bottom - 1);
graphics.DrawLine(Pens.Blue, Padding.Left, Padding.Top, Width - Padding.Left, Height - Padding.Top);
graphics.DrawLine(Pens.Blue, Width - Padding.Left, Padding.Top, Padding.Left, Height - Padding.Top);
}
}
private bool _mouseOver;
protected override void OnMouseEnter(EventArgs e)
{
_mouseOver = true;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
_mouseOver = false;
base.OnMouseLeave(e);
}
private bool _mouseDown;
protected override void OnMouseDown(MouseEventArgs e)
{
_mouseDown = true;
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
_mouseDown = false;
base.OnMouseUp(e);
}
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new FlatStyle FlatStyle { get; set; }
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new FlatButtonAppearance FlatAppearance { get; set; }
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string Text { get; set; }
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Size MinimumSize { get; set; }
#endregion
}
}
and IconType
enum:
namespace MyControls
{
public enum IconType
{
Adjust = 0xf042,
Adn = 0xf170,
AlignCenter = 0xf037,
AlignJustify = 0xf039,
AlignLeft = 0xf036,
AlignRight = 0xf038,
Ambulance = 0xf0f9,
Anchor = 0xf13d,
Android = 0xf17b,
ArrowCircleDown = 0xf0ab,
ArrowCircleLeft = 0xf0a8,
ArrowCircleODown = 0xf01a,
ArrowCircleOLeft = 0xf190,
ArrowCircleORight = 0xf18e,
ArrowCircleOUp = 0xf01b,
ArrowCircleRight = 0xf0a9,
ArrowCircleUp = 0xf0aa,
ArrowDown = 0xf063,
ArrowLeft = 0xf060,
ArrowRight = 0xf061,
ArrowUp = 0xf062,
Arrows = 0xf047,
ArrowsAlt = 0xf0b2,
ArrowsH = 0xf07e,
ArrowsV = 0xf07d,
User = 0xf007,
UserMd = 0xf0f0,
Users = 0xf0c0,
Stop = 0xf04d
}
}
All it needs is to include fontawesome_webfont.ttf in resources.
StringFormat
as last parameter - msdn.microsoft.com/en-us/library/ms142108(v=vs.110).aspx I'musing WinForms and .NET 4.5 if that makes any differences. – Dyslogistic