Cambiar el color del borde en TextBox C #

Tengo el siguiente código:

public class OurTextBox : TextBox { public OurTextBox() : base() { this.SetStyle(ControlStyles.UserPaint, true); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Pen penBorder = new Pen(Color.Gray, 1); Rectangle rectBorder = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1); e.Graphics.DrawRectangle(penBorder, rectBorder); } } 

Esto funciona perfectamente, pero no muestra el texto hasta que se enfoca.

Alguien puede ayudarme? ¿Qué está mal?

Gracias de antemano.

También debe dibujar el texto manualmente.

 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Pen penBorder = new Pen(Color.Gray, 1); Rectangle rectBorder = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1); e.Graphics.DrawRectangle(penBorder, rectBorder); Rectangle textRec = new Rectangle(e.ClipRectangle.X + 1, e.ClipRectangle.Y + 1, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1); TextRenderer.DrawText(e.Graphics, Text, this.Font, textRec, this.ForeColor, this.BackColor, TextFormatFlags.Default); } 

De forma alternativa, puede intentar utilizar el método e.Graphics.DrawString() si TextRenderer no le ofrece los resultados deseados (siempre TextRenderer mejores resultados con este enfoque).

Para cambiar el color del borde de TextBox puede anular el método WndProc y manejar el mensaje WM_NCPAINT . A continuación, obtenga el contexto de dispositivo de ventana del control utilizando GetWindowDC porque queremos dibujar un área de control que no sea cliente. Luego, para dibujar, es suficiente crear un objeto Graphics desde ese contexto, luego dibujar un borde para control.

Para volver a dibujar el control cuando la propiedad BorderColor cambia, puede usar el método RedrawWindow .

Código

Aquí hay un TextBox que tiene una propiedad BorderColor . El control usa BorderColor si los valores de las propiedades son diferentes a Color.Transparent y BorderStyle es su valor predeterminado Fixed3d .

 using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; 
 public class MyTextBox : TextBox { const int WM_NCPAINT = 0x85; const uint RDW_INVALIDATE = 0x1; const uint RDW_IUPDATENOW = 0x100; const uint RDW_FRAME = 0x400; [DllImport("user32.dll")] static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll")] static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); [DllImport("user32.dll")] static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprc, IntPtr hrgn, uint flags); Color borderColor = Color.Blue; public Color BorderColor { get { return borderColor; } set { borderColor = value; RedrawWindow(Handle, IntPtr.Zero, IntPtr.Zero, RDW_FRAME | RDW_IUPDATENOW | RDW_INVALIDATE); } } protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_NCPAINT && BorderColor != Color.Transparent && BorderStyle == System.Windows.Forms.BorderStyle.Fixed3D) { var hdc = GetWindowDC(this.Handle); using (var g = Graphics.FromHdcInternal(hdc)) using (var p = new Pen(BorderColor)) g.DrawRectangle(p, new Rectangle(0, 0, Width - 1, Height - 1)); ReleaseDC(this.Handle, hdc); } } protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); RedrawWindow(Handle, IntPtr.Zero, IntPtr.Zero, RDW_FRAME | RDW_IUPDATENOW | RDW_INVALIDATE); } } 

Resultado

Aquí está el resultado usando diferentes colores y diferentes estados. Todos los estados de estilo de borde son compatibles como puede ver en la imagen de abajo y puede usar cualquier color para borde:

enter image description here

Descargar

Puede clonar o descargar el ejemplo de trabajo:

  • Descargar Zip
  • Repositorio de Github

Hay varias formas de hacer esto y ninguna es ideal. Esta es solo la naturaleza de WinForms. Sin embargo, tienes algunas opciones. Resumiré:

Una forma de lograr lo que desea es insertar un TextBox en un Panel siguiente manera.

 public class BorderedTextBox : Panel { private TextBox textBox; private bool focusedAlways = false; private Color normalBorderColor = Color.Gray; private Color focusedBorderColor = Color.Red; public BorderTextBox() { this.DoubleBuffered = true; this.Padding = new Padding(2); this.TextBox = new TextBox(); this.TextBox.AutoSize = false; this.TextBox.BorderStyle = BorderStyle.None; this.TextBox.Dock = DockStyle.Fill; this.TextBox.Enter += new EventHandler(this.TextBox_Refresh); this.TextBox.Leave += new EventHandler(this.TextBox_Refresh); this.TextBox.Resize += new EventHandler(this.TextBox_Refresh); this.Controls.Add(this.TextBox); } private void TextBox_Refresh(object sender, EventArgs e) { this.Invalidate(); } protected override void OnPaint(PaintEventArgs e) { e.Graphics.Clear(SystemColors.Window); using (Pen borderPen = new Pen(this.TextBox.Focused || FocusedAlways ? focusedBorderColor : normalBorderColor)) { e.Graphics.DrawRectangle(borderPen, new Rectangle(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1)); } base.OnPaint(e); } public TextBox TextBox { get { return textbox; } set { textbox = value; } } public bool FocusedAlaways { get { return focusedAlways; } set { focusedAlways = value; } } } 

También puede hacer esto sin anular ningún control, pero el método anterior es mejor. Lo anterior dibujará un borde cuando el control se enfoque. si desea que el borde FocusedAlways permanente, establezca la propiedad FocusedAlways en True .

Espero que esto ayude.

Establezca el estilo del borde del cuadro de texto en Ninguno y luego escriba este código en el formulario de contenedor “pintura”.

  private void Form1_Paint(object sender, PaintEventArgs e) { System.Drawing.Rectangle rect = new Rectangle(TextBox1.Location.X, TextBox1.Location.Y, TextBox1.ClientSize.Width, TextBox1.ClientSize.Height); rect.Inflate(1, 1); // border thickness System.Windows.Forms.ControlPaint.DrawBorder(e.Graphics, rect, Color.DeepSkyBlue, ButtonBorderStyle.Solid); }