我最近需要编写 Windows NumericUpDown 控件的一个版本,该控件可以突出显示某个值是否是强制的。它需要通过更改控件的背景颜色来做到这一点。我认为这足够简单,但在尝试这样做时,我发现它有一个奇怪的副作用,即无法完全绘制所有控件。
使用下面的代码,我看到了这一点:
当我将控件放在 Windows 窗体上并更改 BackColor 属性时(即到蓝色),整个控件的数字部分都会改变颜色。或者,如果我更改“IsMandatory”属性,则并非所有背景颜色都会更改(它留下了边界)。因此,如果我将 BackColor 更改为 Blue,然后将 IsMandatory 设置为 True,我会得到一个 LightBlue 控件(强制颜色)带有蓝色边框。
鉴于它们都使用相同的代码,我不明白为什么会这样。
想法或解释受到热烈欢迎。
public partial class MyNumericUpDown : NumericUpDown
{
private Boolean _isMandatory = false;
private Color _mandatoryBackColor = Color.LightBlue;
private Color _backColor = Color.FromKnownColor(KnownColor.Window);
[DefaultValue(typeof(Color), "Window"), Description("Overridden property")]
override public Color BackColor
{
get { return _backColor; }
set
{
_backColor = value;
MyResetColors();
}
}
[DefaultValue(typeof(Color), "LightBlue"), Category("Appearance")]
public Color MandatoryBackColor
{
get {return _mandatoryBackColor;}
set
{
_mandatoryBackColor = value;
MyResetColors();
}
}
[DefaultValue(false), Category("Behavior")]
public Boolean IsMandatory
{
get { return _isMandatory; }
set
{
_isMandatory = value;
MyResetColors();
}
}
private void MyResetColors()
{
base.BackColor = (this.IsMandatory ? this.MandatoryBackColor : this.BackColor);
}
}
![Here's what it looks like:](https://i.stack.imgur.com/Z2ZuA.png)
有趣的问题,它演示了重写虚拟成员如何产生意想不到的副作用。核心问题是您的 BackColor 属性 getter,它始终返回 _backColor 属性值,即使您使用 IsMandatory 强制将其设置为不同的值。当 Winforms 需要绘制控件背景时,也会使用该属性 getter。因此,您将返回 Blue,这解释了为什么您在屏幕截图中看到蓝色。
但奇怪的是它仍然适用于控件的文本部分。这是因为 NumericUpdown 是由多个控件组成的。您有一个设置外部边界并且是基类的 ContainerControl,您将重写它的 BackColor 属性。但其内部还有另外两个控件,一个显示文本的 TextBox 和一个显示向上/向下按钮的 Control。您的 BackColor 属性覆盖确实not覆盖它们的 BackColor 属性。因此,文本框部分将使用您分配给 Base.BackColor 的颜色进行绘制
要解决这个问题,您必须停止对 BackColor 撒谎。有了额外的约束,您需要确保这在设计时仍然有效,以便实际的 BackColor 被序列化,而不是 MandatoryColor:
[DefaultValue(typeof(Color), "Window"), Description("Overridden property")]
override public Color BackColor {
get {
return base.BackColor;
}
set {
_backColor = value;
MyResetColors();
}
}
private void MyResetColors() {
base.BackColor = this.IsMandatory && !DesignMode ? this.MandatoryBackColor : _backColor;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)