ユーザーがテキストボックスをクリックするか、フォーカスを当てたときにテキストボックスのBorderColorを変更するにはどうすればよいですか?
これを試して
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();
}
WM_NCPAINT
TextBox
のメッセージ。コントロールにフォーカスがある場合、非クライアントコントロール領域に境界線を描画します。任意の色を使用して境界線を描画できます。
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);
}
}
}
}
結果
コントロールがフォーカスされている間の境界線の描画は、完全にちらつきがありません。
TextBoxのBorderColorプロパティ
現在の投稿では、フォーカスの境界線の色を変更しています。 BorderColor
プロパティをコントロールに追加することもできます。その後、設計時または実行時に要件に基づいて境界線の色を変更できます。次の投稿で、TextBox
プロパティを持つBorderColor
のより完成したバージョンを投稿しました。
これは、TextBoxの境界線の色を設定する究極のソリューションです。
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はこれが得意ではありませんでしたが、少し面倒です。
1つの方法として、TextBoxをパネルに埋め込み、そこからフォーカスに基づいて描画を管理する方法があります。
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);
}
}
[テキストボックスの境界線スタイル]を[なし]に設定してから、このコードをコンテナフォームの "ペイント"イベントに書き込みます。
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);
}
OnPaint
を使用してコントロールにカスタム境界線を描画することは問題ありません。ただし、OnPaint
を使用して効率を上げ、時間を最小限に抑える方法を知ってください。カスタムペイントルーチンの使用中にGUIが遅延する場合は、これをお読みください。 。NetアプリケーションでOnPaintを使用する正しい方法は何ですか?
PraVnの受け入れられた答えは単純に見えるかもしれませんが、実際には非効率的だからです。上記の回答に掲載されているようなカスタムコントロールを使用する方がはるかに優れています。
パフォーマンスはアプリケーションの問題ではないかもしれませんが、それは小さいためです。しかし、多くのカスタムOnPaintルーチンを備えた大規模なアプリケーションでは、PraVnが示した方法を使用するのは間違ったアプローチです。