Comment puis-je changer la couleur de bordure de la zone de texte lorsqu'un utilisateur clique dessus ou se concentre dessus?
essaye ça
bool focus = false;
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (focus)
{
textBox1.BorderStyle = BorderStyle.None;
Pen p = new Pen(Color.Red);
Graphics g = e.Graphics;
int variance = 3;
g.DrawRectangle(p, new Rectangle(textBox1.Location.X - variance, textBox1.Location.Y - variance, textBox1.Width + variance, textBox1.Height +variance ));
}
else
{
textBox1.BorderStyle = BorderStyle.FixedSingle;
}
}
private void textBox1_Enter(object sender, EventArgs e)
{
focus = true;
this.Refresh();
}
private void textBox1_Leave(object sender, EventArgs e)
{
focus = false;
this.Refresh();
}
Vous pouvez gérer WM_NCPAINT
message de TextBox
et dessiner une bordure sur la zone de contrôle non client si le contrôle a le focus. Vous pouvez utiliser n'importe quelle couleur pour dessiner une bordure:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class ExTextBox : TextBox
{
[DllImport("user32")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);
private const int WM_NCPAINT = 0x85;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCPAINT && this.Focused)
{
var dc = GetWindowDC(Handle);
using (Graphics g = Graphics.FromHdc(dc))
{
g.DrawRectangle(Pens.Red, 0, 0, Width - 1, Height - 1);
}
}
}
}
Résultat
La peinture des frontières lorsque le contrôle est concentré est totalement sans scintillement:
Remarque
Dans le post actuel, je viens de changer la couleur de la bordure sur le focus. Vous pouvez également ajouter une propriété BorderColor
au contrôle. Vous pouvez ensuite modifier la couleur de la bordure en fonction de vos besoins au moment de la conception ou de l'exécution. Ici j'ai posté une version plus complète de TextBox
qui a la propriété BorderColor
:
C’est une solution ultime pour définir la couleur de bordure d’une zone de texte:
public class BorderedTextBox : UserControl
{
TextBox textBox;
public BorderedTextBox()
{
textBox = new TextBox()
{
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(-1, -1),
Anchor = AnchorStyles.Top | AnchorStyles.Bottom |
AnchorStyles.Left | AnchorStyles.Right
};
Control container = new ContainerControl()
{
Dock = DockStyle.Fill,
Padding = new Padding(-1)
};
container.Controls.Add(textBox);
this.Controls.Add(container);
DefaultBorderColor = SystemColors.ControlDark;
FocusedBorderColor = Color.Red;
BackColor = DefaultBorderColor;
Padding = new Padding(1);
Size = textBox.Size;
}
public Color DefaultBorderColor { get; set; }
public Color FocusedBorderColor { get; set; }
public override string Text
{
get { return textBox.Text; }
set { textBox.Text = value; }
}
protected override void OnEnter(EventArgs e)
{
BackColor = FocusedBorderColor;
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e)
{
BackColor = DefaultBorderColor;
base.OnLeave(e);
}
protected override void SetBoundsCore(int x, int y,
int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, width, textBox.PreferredHeight, specified);
}
}
WinForms n’a jamais été bon dans ce domaine et c’est un peu pénible.
Une façon d'essayer est d'incorporer une zone de texte dans un panneau, puis de gérer le dessin en fonction du focus à partir de là:
public class BorderTextBox : Panel {
private Color _NormalBorderColor = Color.Gray;
private Color _FocusBorderColor = Color.Blue;
public TextBox EditBox;
public BorderTextBox() {
this.DoubleBuffered = true;
this.Padding = new Padding(2);
EditBox = new TextBox();
EditBox.AutoSize = false;
EditBox.BorderStyle = BorderStyle.None;
EditBox.Dock = DockStyle.Fill;
EditBox.Enter += new EventHandler(EditBox_Refresh);
EditBox.Leave += new EventHandler(EditBox_Refresh);
EditBox.Resize += new EventHandler(EditBox_Refresh);
this.Controls.Add(EditBox);
}
private void EditBox_Refresh(object sender, EventArgs e) {
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.Clear(SystemColors.Window);
using (Pen borderPen = new Pen(this.EditBox.Focused ? _FocusBorderColor : _NormalBorderColor)) {
e.Graphics.DrawRectangle(borderPen, new Rectangle(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1));
}
base.OnPaint(e);
}
}
définissez le style de la zone de texte sur Aucun puis écrivez ce code dans le formulaire de conteneur, événement "Paint"
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);
}
Utiliser OnPaint
pour dessiner une bordure personnalisée sur vos contrôles est acceptable. Mais sachez comment utiliser OnPaint
pour gagner en efficacité et gagner du temps. Lisez ceci si vous rencontrez une interface utilisateur lente lors de l’utilisation de routines de peinture personnalisées: Quelle est la bonne façon d’utiliser OnPaint dans les applications .Net?
Parce que la réponse acceptée de PraVn peut sembler simple, mais est en réalité inefficace. Utiliser un contrôle personnalisé, comme ceux affichés dans les réponses ci-dessus, est bien meilleur.
Les performances ne sont peut-être pas un problème dans votre application, car elles sont petites, mais pour les applications plus volumineuses comportant de nombreuses routines OnPaint personnalisées, il est erroné d'utiliser les indications de PraVn.