Skip to content

Instantly share code, notes, and snippets.

@sinairv
Created August 8, 2016 05:59
Show Gist options
  • Save sinairv/9826359bb8fc0666a9b5f6df0c89c876 to your computer and use it in GitHub Desktop.
Save sinairv/9826359bb8fc0666a9b5f6df0c89c876 to your computer and use it in GitHub Desktop.
CardView Windows Forms Control
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace WinFormsImage
{
public class CardView : PictureBox
{
public CardView()
{
BackColor = Color.White;
}
private string _headerText = "Header";
private Color _headerColor = Color.Black;
private Font _headerFont = new Font("Arial", 14F, FontStyle.Regular);
private string _bodyText = "Body";
private Color _bodyColor = Color.Black;
private Font _bodyFont = new Font("Arial", 46F, FontStyle.Bold);
private Color _borderColor = Color.DarkGray;
private int _borderRadius = 5;
private int _cardPadding = 20;
[Category("Header")]
[Browsable(true)]
public string HeaderText
{
get { return _headerText; }
set
{
if (!Equals(_headerText, value))
{
_headerText = value;
OnHeaderTextChanged();
}
}
}
[Category("Header")]
[Browsable(true)]
public Color HeaderColor
{
get { return _headerColor; }
set
{
if (!Equals(_headerColor, value))
{
_headerColor = value;
OnHeaderColorChanged();
}
}
}
[Category("Header")]
[Browsable(true)]
public Font HeaderFont
{
get { return _headerFont; }
set
{
if (!Equals(_headerFont, value))
{
_headerFont = value;
OnHeaderFontChanged();
}
}
}
[Category("Body")]
[Browsable(true)]
public string BodyText
{
get { return _bodyText; }
set
{
if (!Equals(_bodyText, value))
{
_bodyText = value;
OnBodyTextChanged();
}
}
}
[Category("Body")]
[Browsable(true)]
public Color BodyColor
{
get { return _bodyColor; }
set
{
if (!Equals(_bodyColor, value))
{
_bodyColor = value;
OnBodyColorChanged();
}
}
}
[Category("Body")]
[Browsable(true)]
public Font BodyFont
{
get { return _bodyFont; }
set
{
if (!Equals(_bodyFont, value))
{
_bodyFont = value;
OnBodyFontChanged();
}
}
}
[Category("CardView")]
[Browsable(true)]
public Color BorderColor
{
get { return _borderColor; }
set
{
if (!Equals(_borderColor, value))
{
_borderColor = value;
OnBorderColorChanged();
}
}
}
[Category("CardView")]
[Browsable(true)]
public int BorderRadius
{
get { return _borderRadius; }
set
{
if (_borderRadius != value)
{
_borderRadius = value;
OnBorderRadiusChanged();
}
}
}
[Category("CardView")]
[Browsable(true)]
public int CardPadding
{
get { return _cardPadding; }
set
{
if (_cardPadding != value)
{
_cardPadding = value;
OnCardPaddingChanged();
}
}
}
public event EventHandler HeaderTextChanged;
public event EventHandler HeaderColorChanged;
public event EventHandler HeaderFontChanged;
public event EventHandler BodyTextChanged;
public event EventHandler BodyColorChanged;
public event EventHandler BodyFontChanged;
public event EventHandler BorderColorChanged;
public event EventHandler BorderRadiusChanged;
public event EventHandler CardPaddingChanged;
protected virtual void OnHeaderTextChanged()
{
HeaderTextChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnHeaderColorChanged()
{
HeaderColorChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnHeaderFontChanged()
{
HeaderFontChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnBodyTextChanged()
{
BodyTextChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnBodyColorChanged()
{
BodyColorChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnBodyFontChanged()
{
BodyFontChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnBorderColorChanged()
{
BorderColorChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnBorderRadiusChanged()
{
BorderRadiusChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected virtual void OnCardPaddingChanged()
{
CardPaddingChanged?.Invoke(this, EventArgs.Empty);
Refresh();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
Refresh();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
var graphics = pe.Graphics;
int contentHeight = 0;
int contentWidth = 0;
SizeF headerSize = SizeF.Empty;
SizeF bodySize = SizeF.Empty;
if (!String.IsNullOrWhiteSpace(_headerText))
{
headerSize = graphics.MeasureString(_headerText, _headerFont);
contentHeight += (int)headerSize.Height;
contentWidth = Math.Max(contentWidth, (int)headerSize.Width);
}
if (!String.IsNullOrWhiteSpace(_bodyText))
{
bodySize = graphics.MeasureString(_bodyText, _bodyFont);
contentHeight += (int)bodySize.Height;
contentWidth = Math.Max(contentWidth, (int)bodySize.Width);
}
int maxTextWidth = Width - (2 * CardPadding) - 1;
int maxTextHeight = Height - (2 * CardPadding) - 1;
contentWidth = Math.Min(maxTextWidth, contentWidth);
contentHeight = Math.Min(maxTextHeight, contentHeight);
// the rectangle to fit the 2 labels
var contentRect = new Rectangle((Width - contentWidth) / 2, (Height - contentHeight) / 2,
contentWidth, contentHeight);
// the rectangle to fit the header label
var headerRect = new Rectangle(contentRect.Left, contentRect.Top, contentRect.Width, (int)headerSize.Height);
// the rectangle to fit the body label
var bodyRect = new Rectangle(contentRect.Left, contentRect.Top + (int)headerSize.Height,
contentRect.Width, (int) bodySize.Height);
TextRenderer.DrawText(graphics, _headerText, _headerFont, headerRect, _headerColor, TextFormatFlags.HorizontalCenter);
TextRenderer.DrawText(graphics, _bodyText, _bodyFont, bodyRect, _bodyColor, TextFormatFlags.HorizontalCenter);
// the rectangle to fit the labels + padding
var borderRect = Rectangle.Inflate(contentRect, _cardPadding, _cardPadding);
// uncomment to debug
// graphics.DrawRoundedCornerRectangle(contentRect, _borderRadius, _borderColor, 1.5f);
graphics.DrawRoundedCornerRectangle(borderRect, _borderRadius, _borderColor, 1.5f);
}
}
}
using System.Drawing.Drawing2D;
// ReSharper disable once CheckNamespace
namespace System.Drawing
{
public static class GraphicsExtensions
{
public static void DrawRoundedCornerRectangle(this Graphics gfx, Rectangle rectangle, int borderRadius, Color borderColor, float penWidth)
{
Pen borderPen = new Pen(borderColor, penWidth);
borderPen.EndCap = borderPen.StartCap = LineCap.Round;
GraphicsPath gfxPath = new GraphicsPath();
gfxPath.AddArc(rectangle.X, rectangle.Y, borderRadius, borderRadius, 180, 90);
gfxPath.AddArc(rectangle.X + rectangle.Width - borderRadius, rectangle.Y, borderRadius, borderRadius, 270, 90);
gfxPath.AddArc(rectangle.X + rectangle.Width - borderRadius, rectangle.Y + rectangle.Height - borderRadius, borderRadius, borderRadius, 0, 90);
gfxPath.AddArc(rectangle.X, rectangle.Y + rectangle.Height - borderRadius, borderRadius, borderRadius, 90, 90);
gfxPath.CloseAllFigures();
gfx.DrawPath(borderPen, gfxPath);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment