c# – 文本框自定义onPaint

我正在尝试为我的文本框创建一个自定义onPaint,它正在工作… it is working但是当我尝试输入内容时,a textbox is rendering above the textbox.

这是我的构造函数:

public TextBox()
{
  Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
  BackColor = Color.White;
  BorderColor = Color.Gray;
  BorderStyle = BorderStyle.None;
  SetStyle(ControlStyles.UserPaint, true);
}

和onPaint:

protected override void OnPaint(PaintEventArgs e)
{
  Graphics g = e.Graphics;
  g.FillRectangle(backgroundBrush, 0, 0, this.Width, this.Height);

  SizeF fontSize = g.MeasureString(Text, Font);
  g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF(5, 5), cFormat);

  g.DrawRectangle(borderPen, borderPen.Width / 2, borderPen.Width / 2,
                  this.Width - borderPen.Width, this.Height - borderPen.Width);
}
如果你只想要一个带有一些自定义边框(宽度和颜色)的自定义TextBox,我在这里有两个解决方案:

>使用ControlPaint,这将允许您绘制一些样式和颜色的边框,但不能使用画笔来更多地绘制(像HatchBrush可以做的):

public class CustomTextBox : TextBox
{
    [DllImport("user32")]
    private static extern IntPtr GetWindowDC(IntPtr hwnd);
    struct RECT
    {
      public int left, top, right, bottom;
    }
    struct NCCALSIZE_PARAMS
    {
      public RECT newWindow;
      public RECT oldWindow;
      public RECT clientWindow;
      IntPtr windowPos;
    }            
    float clientPadding = 2;  
    float actualBorderWidth = 4;
    Color borderColor = Color.Red;      
    protected override void WndProc(ref Message m)
    {
      //We have to change the clientsize to make room for borders
      //if not, the border is limited in how thick it is.
      if (m.Msg == 0x83) //WM_NCCALCSIZE   
      {
        if (m.WParam == IntPtr.Zero)
        {
            RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
            rect.left += clientPadding;
            rect.right -= clientPadding;
            rect.top += clientPadding;
            rect.bottom -= clientPadding;
            Marshal.StructureToPtr(rect, m.LParam, false);
        }
        else
        {
            NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
            rects.newWindow.left += clientPadding;
            rects.newWindow.right -= clientPadding;
            rects.newWindow.top += clientPadding;
            rects.newWindow.bottom -= clientPadding;
            Marshal.StructureToPtr(rects, m.LParam, false);
        }
      }
      if (m.Msg == 0x85) //WM_NCPAINT    
      {         
         IntPtr wDC = GetWindowDC(Handle);
         using(Graphics g = Graphics.FromHdc(wDC)){                                                      
           ControlPaint.DrawBorder(g, new Rectangle(0,0,Size.Width, Size.Height), borderColor, actualBorderWidth, ButtonBorderStyle.Solid,
         borderColor, actualBorderWidth, ButtonBorderStyle.Solid, borderColor, actualBorderWidth, ButtonBorderStyle.Solid,
         borderColor, actualBorderWidth, ButtonBorderStyle.Solid); 
         }   
         return;          
      }
      base.WndProc(ref m);
    }
}

这是文本框快照:

>使用Graphics的FillRegion方法用各种Brush绘制边框,这里我使用HatchBrush:

public class CustomTextBox : TextBox
{
  [DllImport("user32")]
  private static extern IntPtr GetWindowDC(IntPtr hwnd);
  struct RECT
  {
    public int left, top, right, bottom;
  }
  struct NCCALSIZE_PARAMS
  {
    public RECT newWindow;
    public RECT oldWindow;
    public RECT clientWindow;
    IntPtr windowPos;
  }         
  int clientPadding = 2;   
  int actualBorderWidth = 4;     
  protected override void WndProc(ref Message m)
  {
      //We have to change the clientsize to make room for borders
      //if not, the border is limited in how thick it is.
      if (m.Msg == 0x83) //WM_NCCALCSIZE   
      {
        if (m.WParam == IntPtr.Zero)
        {
            RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
            rect.left += clientPadding;
            rect.right -= clientPadding;
            rect.top += clientPadding;
            rect.bottom -= clientPadding;
            Marshal.StructureToPtr(rect, m.LParam, false);
        }
        else
        {
            NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS));
            rects.newWindow.left += clientPadding;
            rects.newWindow.right -= clientPadding;
            rects.newWindow.top += clientPadding;
            rects.newWindow.bottom -= clientPadding;
            Marshal.StructureToPtr(rects, m.LParam, false);
        }
      }
      if (m.Msg == 0x85) //WM_NCPAINT
      {                 
        IntPtr wDC = GetWindowDC(Handle);
        using(Graphics g = Graphics.FromHdc(wDC)){                                                
          Rectangle rect = new Rectangle(0,0,Width,Height);
          Rectangle inner = new Rectangle(0, 0, Width, Height);
          inner.Offset(actualBorderWidth + 2, actualBorderWidth + 2);
          inner.Width -= 2 * actualBorderWidth + 4;
          inner.Height -= 2 * actualBorderWidth + 4;
          Region r = new Region(rect);
          r.Xor(inner);
          using (System.Drawing.Drawing2D.HatchBrush brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.SmallCheckerBoard, Color.Green, Color.Red))
          {                    
            g.FillRegion(brush, r);
          }
        }
        return;
      }
      base.WndProc(ref m);
  }
}

这是文本框快照:

https://stackoverflow.com/questions/17414693/textbox-custom-onpaint

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c# – 文本框自定义onPaint