覆盖在C#中绘制一个控件

时间:2012-10-10 10:04:12

标签: c# override

任何人都可以提供有关如何在C#中覆盖绘制事件的基本教程吗?我没有太多的C#经验,这是我不容易理解的一部分因为我不能遵循一些教程和技巧,因为我没有在C#中覆盖覆盖的概念。

3 个答案:

答案 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)

这是按钮

enter image description here

我想分享我的代码:

按钮类:

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)); 
        }
    }
}

享受!