[英]TextBox Not using Readonly color if background has been changed
It seems that when you set the BackColor of a TextBox, Readonly ceases to affect the BackColor from then on.似乎当您设置 TextBox 的 BackColor 时,Readonly 从那时起不再影响 BackColor。 I have user control where, a decoration engine tracks validation, and highlights textboxes a certain color when the value has been validated.
我有用户控制,装饰引擎跟踪验证,并在验证值时以某种颜色突出显示文本框。 However, once I've assigned Color.Yellow or SystemColors.Window to the TextBox.BackColor, setting TextBox.Readonly does nothing.
但是,一旦我将 Color.Yellow 或 SystemColors.Window 分配给 TextBox.BackColor,设置 TextBox.Readonly 就什么也不做。
This is extremely easy to reproduce:这非常容易重现:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.ReadOnly = !textBox1.ReadOnly;
}
private void button2_Click(object sender, EventArgs e)
{
textBox2.ReadOnly = !textBox2.ReadOnly;
}
private void button3_Click(object sender, EventArgs e)
{
textBox2.BackColor = Color.Blue;
}
private void textBox1_ReadOnlyChanged(object sender, EventArgs e)
{
label1.Text = $"Readonly: {textBox1.ReadOnly}{Environment.NewLine}Color: {textBox1.BackColor}";
}
private void textBox2_ReadOnlyChanged(object sender, EventArgs e)
{
label2.Text = $"Readonly: {textBox2.ReadOnly}{Environment.NewLine}Color: {textBox2.BackColor}";
}
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(138, 286);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(219, 286);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 3;
this.button2.Text = "button2";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Location = new System.Drawing.Point(300, 286);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(75, 23);
this.button3.TabIndex = 4;
this.button3.Text = "button3";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(108, 190);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 22);
this.textBox1.TabIndex = 5;
this.textBox1.ReadOnlyChanged += new System.EventHandler(this.textBox1_ReadOnlyChanged);
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(308, 190);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(100, 22);
this.textBox2.TabIndex = 6;
this.textBox2.ReadOnlyChanged += new System.EventHandler(this.textBox2_ReadOnlyChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(105, 215);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 17);
this.label1.TabIndex = 7;
this.label1.Text = "Readonly: ";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(305, 215);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(72, 17);
this.label2.TabIndex = 8;
this.label2.Text = "Readonly:";
//
// Form1
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
}
Simply run that form, click button1 and button2 repeatedly, and both textboxes will cycle from default Window to Control background colors as the readonly property changes.只需运行该表单,重复单击 button1 和 button2,随着只读属性的更改,两个文本框将从默认窗口循环到控制背景颜色。 Button3, sets the textbox2 backcolor to Blue, and from then on, clicking button2 has no affect on the backcolor.
Button3,将textbox2的背景色设置为蓝色,从那时起,点击button2对背景色没有任何影响。
I Do NOT want this behavior.我不想要这种行为。 I want to affect the backcolor, but I want readonly to supersede any custom backcolor i have assigned.
我想影响背景色,但我希望 readonly 取代我分配的任何自定义背景色。
How do i achieve this?我如何实现这一目标?
Your question as I understand it is how to achieve a visual state where the textbox color uses the default value of SystemColors.Control
when the TextBox
is in the ReadOnly
state and a different custom color when it's not.据我了解,您的问题是如何实现一种视觉状态,其中文本框颜色在
TextBox
处于ReadOnly
状态时使用SystemColors.Control
的默认值,而在非只读状态时使用不同的自定义颜色。
The easiest way I know of to do that is to handle the ReadOnlyChanged
event of the TextBox
controls.我知道的最简单的方法是处理
TextBox
控件的ReadOnlyChanged
事件。 For example:例如:
public Form1()
{
InitializeComponent();
textBox2.ReadOnlyChanged += (sender, e) =>
{
textBox2.BackColor = textBox2.ReadOnly ? SystemColors.Control : Color.Blue;
};
}
and also checking the state first when you set the custom background color:并在设置自定义背景颜色时首先检查状态:
private void button3_Click(object sender, EventArgs e)
{
textBox2.BackColor = textBox2.ReadOnly ? SystemColors.Control : Color.Blue;
}
Well, apparently, because of "reasons", there is not "slick" way to achieve this, but i did find that if you set the BackColor = Color.Empty, the readonly behavior returns.好吧,显然,由于“原因”,没有“巧妙”的方式来实现这一点,但我确实发现如果你设置 BackColor = Color.Empty,只读行为会返回。 THis is due to the unchangeable code in TextBoxBase:
这是由于 TextBoxBase 中不可更改的代码:
public override Color BackColor {
get {
if (ShouldSerializeBackColor()) {
return base.BackColor;
}
else if (this.ReadOnly) {
return SystemColors.Control;
} else {
return SystemColors.Window;
}
}
set {
base.BackColor = value;
}
}
The ShouldSerializeBackColor() will return false if you set the backcolor to Color.Empty, allowing the second part of that if-else condition to process, and voila.如果将背景色设置为 Color.Empty,ShouldSerializeBackColor() 将返回 false,从而允许处理 if-else 条件的第二部分,瞧。 It ain't pretty, but at least it works.
它不漂亮,但至少它有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.