2012-10-10 85 views
2

任何人都可以提供有關如何重寫C#中的繪畫事件的基本教程?我沒有太多的C#經驗,這是我不容易得到的一部分,因爲我不能遵循一些教程和技巧,因爲我沒有得到在C#中重寫的概念。覆蓋在C#中繪製控件

+0

基本上控制(在WinForms中,我猜你指的是這個)有一個內置的方法,它在屏幕上繪製自己。通過在衍生中重寫該方法,你就是說不要做你平常做的事情,這樣做。 –

+0

你的問題並不一致,但你可能想閱讀下面的鏈接。 這裏是官方(第一手)定義和使用:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx 請記住一些控件被封裝,例如文本框,沒有onpaint(我記得)。 – Rolice

+0

您是否嘗試過重寫'protected void OnPaint(...)'(就像[this](http://msdn.microsoft.com/zh-cn/library/cksxshce.aspx)文章)?只是想了解你的基線 –

回答

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

例如:

public class FirstControl : Control{ 
    public FirstControl() {} 
    protected override void OnPaint(PaintEventArgs e) { 
     base.OnPaint(e);  
     e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle); 
    } 
} 

只是不在寫作之前忘記打電話給底漆處理器

0

這是按鈕

enter image description here

我想和大家分享我的代碼:

Button類:

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對象。

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

Enjoy!