任何人都可以提供有关如何在C#中覆盖绘制事件的基本教程吗?我没有太多的C#经验,这是我不容易理解的一部分因为我不能遵循一些教程和技巧,因为我没有在C#中覆盖覆盖的概念。
答案 0 :(得分:2)
这是一个非常基本的例子,它将(应该!)绘制一个红色的'X':
public class FacadeControl : Control
{
private Pen invalidPen;
public FacadeControl()
{
invalidPen = new Pen(Color.Red, 2);
SetStyle(ControlStyles.ResizeRedraw, true); // make sure the control is redrawn every time it is resized
}
protected override void OnPaint(PaintEventArgs pe)
{
// get the graphics object to use to draw
Graphics g = pe.Graphics;
g.DrawLine(invalidPen, 0, 0, Width, Height);
g.DrawLine(invalidPen, 0, Height, Width, 0);
}
}
}
答案 1 :(得分:1)
例如:
public class FirstControl : Control{
public FirstControl() {}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle);
}
}
在写你的之前不要忘记调用基础绘制处理程序
答案 2 :(得分:0)
这是按钮
我想分享我的代码:
按钮类:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
namespace Controles.Buttons
{
/// <summary>
/// Clase personalizada button.
/// Jorge Arturo Avilés Nuñez
/// Zapopan, Jalisco, México
/// 18-DIC-2017
/// </summary>
public class SansationRoundButton : Button
{
#region members
private TextRenderingHint _hint = TextRenderingHint.AntiAlias;
private const int FlagMouseOver = 0x0001;
private const int FlagMouseDown = 0x0002;
private int state = 0;
#endregion
#region Constructor
public SansationRoundButton()
{
this.FlatStyle = FlatStyle.Flat;
this.FlatAppearance.BorderSize = 0;
this.Font = new System.Drawing.Font("Sansation", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0);
this.UseVisualStyleBackColor = true;
this.Cursor = Cursors.Hand;
}
#endregion
#region Internal methods and properties
internal bool OwnerDraw
{
get
{
return FlatStyle != FlatStyle.System;
}
}
internal bool MouseIsOver
{
get
{
return GetFlag(FlagMouseOver);
}
}
#endregion
#region Private methods
private bool GetFlag(int flag)
{
return ((state & flag) == flag);
}
private void SetFlag(int flag, bool value)
{
bool oldValue = ((state & flag) != 0);
if (value)
state |= flag;
else
state &= ~flag;
if (OwnerDraw && (flag & FlagMouseDown) != 0 && value != oldValue)
AccessibilityNotifyClients(AccessibleEvents.StateChange, -1);
}
#endregion
#region Overrides
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
SetFlag(FlagMouseOver, true);
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
SetFlag(FlagMouseOver, false);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
e.Graphics.TextRenderingHint = this.TextRenderingHint;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Color backColor = this.MouseIsOver ? this.BackColorMouseOver : this.BackColor;
Color borderColor = this.MouseIsOver ? this.BorderColorMouseOver : this.BorderColor;
e.Graphics.DrawRoundedRectangle(new Pen(borderColor), 0, 0, this.Width - 1, this.Height - 1, 10);
e.Graphics.FillRoundedRectangle(new SolidBrush(backColor), 0, 0, this.Width - 1, this.Height - 1, 10);
StringFormat sr = BaseControl.CreateStringFormat(this, this.TextAlign, false, this.UseMnemonic);
e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(ForeColor), ClientRectangle, sr);
}
#endregion
#region public properties
public TextRenderingHint TextRenderingHint
{
get { return this._hint; }
set { this._hint = value; }
}
public new bool ShowKeyboardCues
{
get
{
return base.ShowKeyboardCues;
}
}
public Color BackColorMouseOver { get; set; } = Color.Red;
public Color BorderColor { get; set; } = Color.Black;
public Color BorderColorMouseOver { get; set; } = Color.Black;
#endregion
}
}
此类BaseControl创建一个StringFormat对象的新实例,该实例是从Graphics对象调用DrawString方法所必需的。
using System.Drawing;
using System.Windows.Forms;
namespace Controles.Buttons
{
public class BaseControl
{
private static readonly ContentAlignment anyRight = ContentAlignment.TopRight | ContentAlignment.MiddleRight | ContentAlignment.BottomRight;
private static readonly ContentAlignment anyBottom = ContentAlignment.BottomLeft | ContentAlignment.BottomCenter | ContentAlignment.BottomRight;
private static readonly ContentAlignment anyCenter = ContentAlignment.TopCenter | ContentAlignment.MiddleCenter | ContentAlignment.BottomCenter;
private static readonly ContentAlignment anyMiddle = ContentAlignment.MiddleLeft | ContentAlignment.MiddleCenter | ContentAlignment.MiddleRight;
static StringAlignment TranslateAlignment(ContentAlignment align)
{
StringAlignment result;
if ((align & anyRight) != 0)
result = StringAlignment.Far;
else if ((align & anyCenter) != 0)
result = StringAlignment.Center;
else
result = StringAlignment.Near;
return result;
}
static StringAlignment TranslateLineAlignment(ContentAlignment align)
{
StringAlignment result;
if ((align & anyBottom) != 0)
{
result = StringAlignment.Far;
}
else if ((align & anyMiddle) != 0)
{
result = StringAlignment.Center;
}
else
{
result = StringAlignment.Near;
}
return result;
}
static StringFormat StringFormatForAlignment(ContentAlignment align)
{
StringFormat output = new StringFormat();
output.Alignment = TranslateAlignment(align);
output.LineAlignment = TranslateLineAlignment(align);
return output;
}
public static StringFormat CreateStringFormat(SansationRoundButton ctl, ContentAlignment textAlign, bool showEllipsis, bool useMnemonic)
{
StringFormat stringFormat = StringFormatForAlignment(textAlign);
// Adjust string format for Rtl controls
if (ctl.RightToLeft == RightToLeft.Yes)
{
stringFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
}
if (showEllipsis)
{
stringFormat.Trimming = StringTrimming.EllipsisCharacter;
stringFormat.FormatFlags |= StringFormatFlags.LineLimit;
}
if (!useMnemonic)
{
stringFormat.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
}
else if (ctl.ShowKeyboardCues)
{
stringFormat.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Show;
}
else
{
stringFormat.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.Hide;
}
if (ctl.AutoSize)
{
stringFormat.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
}
return stringFormat;
}
}
}
最后,这个类用于创建和填充矩形。
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Plasmoid.Extensions
{
static class GraphicsExtension
{
private static GraphicsPath GenerateRoundedRectangle(
this Graphics graphics,
RectangleF rectangle,
float radius)
{
float diameter;
GraphicsPath path = new GraphicsPath();
if (radius <= 0.0F)
{
path.AddRectangle(rectangle);
path.CloseFigure();
return path;
}
else
{
if (radius >= (Math.Min(rectangle.Width, rectangle.Height)) / 2.0)
return graphics.GenerateCapsule(rectangle);
diameter = radius * 2.0F;
SizeF sizeF = new SizeF(diameter, diameter);
RectangleF arc = new RectangleF(rectangle.Location, sizeF);
path.AddArc(arc, 180, 90);
arc.X = rectangle.Right - diameter;
path.AddArc(arc, 270, 90);
arc.Y = rectangle.Bottom - diameter;
path.AddArc(arc, 0, 90);
arc.X = rectangle.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
}
return path;
}
private static GraphicsPath GenerateCapsule(
this Graphics graphics,
RectangleF baseRect)
{
float diameter;
RectangleF arc;
GraphicsPath path = new GraphicsPath();
try
{
if (baseRect.Width > baseRect.Height)
{
diameter = baseRect.Height;
SizeF sizeF = new SizeF(diameter, diameter);
arc = new RectangleF(baseRect.Location, sizeF);
path.AddArc(arc, 90, 180);
arc.X = baseRect.Right - diameter;
path.AddArc(arc, 270, 180);
}
else if (baseRect.Width < baseRect.Height)
{
diameter = baseRect.Width;
SizeF sizeF = new SizeF(diameter, diameter);
arc = new RectangleF(baseRect.Location, sizeF);
path.AddArc(arc, 180, 180);
arc.Y = baseRect.Bottom - diameter;
path.AddArc(arc, 0, 180);
}
else path.AddEllipse(baseRect);
}
catch { path.AddEllipse(baseRect); }
finally { path.CloseFigure(); }
return path;
}
/// <summary>
/// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius
/// for the arcs that make the rounded edges.
/// </summary>
/// <param name="brush">System.Drawing.Pen that determines the color, width and style of the rectangle.</param>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
/// <param name="width">Width of the rectangle to draw.</param>
/// <param name="height">Height of the rectangle to draw.</param>
/// <param name="radius">The radius of the arc used for the rounded edges.</param>
public static void DrawRoundedRectangle(
this Graphics graphics,
Pen pen,
float x,
float y,
float width,
float height,
float radius)
{
RectangleF rectangle = new RectangleF(x, y, width, height);
GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius);
SmoothingMode old = graphics.SmoothingMode;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.DrawPath(pen, path);
graphics.SmoothingMode = old;
}
/// <summary>
/// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius
/// for the arcs that make the rounded edges.
/// </summary>
/// <param name="brush">System.Drawing.Pen that determines the color, width and style of the rectangle.</param>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw.</param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw.</param>
/// <param name="width">Width of the rectangle to draw.</param>
/// <param name="height">Height of the rectangle to draw.</param>
/// <param name="radius">The radius of the arc used for the rounded edges.</param>
public static void DrawRoundedRectangle(
this Graphics graphics,
Pen pen,
int x,
int y,
int width,
int height,
int radius)
{
graphics.DrawRoundedRectangle(
pen,
Convert.ToSingle(x),
Convert.ToSingle(y),
Convert.ToSingle(width),
Convert.ToSingle(height),
Convert.ToSingle(radius));
}
/// <summary>
/// Fills the interior of a rounded rectangle specified by a pair of coordinates, a width, a height
/// and the radius for the arcs that make the rounded edges.
/// </summary>
/// <param name="brush">System.Drawing.Brush that determines the characteristics of the fill.</param>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle to fill.</param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle to fill.</param>
/// <param name="width">Width of the rectangle to fill.</param>
/// <param name="height">Height of the rectangle to fill.</param>
/// <param name="radius">The radius of the arc used for the rounded edges.</param>
public static void FillRoundedRectangle(
this Graphics graphics,
Brush brush,
float x,
float y,
float width,
float height,
float radius)
{
RectangleF rectangle = new RectangleF(x, y, width, height);
GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius);
SmoothingMode old = graphics.SmoothingMode;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.FillPath(brush, path);
graphics.SmoothingMode = old;
}
/// <summary>
/// Fills the interior of a rounded rectangle specified by a pair of coordinates, a width, a height
/// and the radius for the arcs that make the rounded edges.
/// </summary>
/// <param name="brush">System.Drawing.Brush that determines the characteristics of the fill.</param>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle to fill.</param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle to fill.</param>
/// <param name="width">Width of the rectangle to fill.</param>
/// <param name="height">Height of the rectangle to fill.</param>
/// <param name="radius">The radius of the arc used for the rounded edges.</param>
public static void FillRoundedRectangle(
this Graphics graphics,
Brush brush,
int x,
int y,
int width,
int height,
int radius)
{
graphics.FillRoundedRectangle(
brush,
Convert.ToSingle(x),
Convert.ToSingle(y),
Convert.ToSingle(width),
Convert.ToSingle(height),
Convert.ToSingle(radius));
}
}
}
享受!