我正在尝试使用几个属性扩展 System.Windows.Forms.Button 类。 我想要实现的是基于启用属性,为 BackColor 和 ForeColor 设置两种不同的颜色。
设计师的一切看起来都不错, 但是,当我尝试改变颜色时,没有任何反应。 如果我关闭表单窗口并重新打开它,则值将丢失或重置为默认值。
我不知道我错过了什么,但显然我做错了或根本没做过。有什么想法吗?
提前感谢您的帮助
这是我目前用来继承Button的类:
public partial class ZButton : Button
{
public ZButton()
{
InitializeComponent();
SetAppearance();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
[Description("The background color of the component"), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public new EnableDisableAppearance BackColor { get { return backcolor; } set { backcolor = value; SetAppearance(); } }
private EnableDisableAppearance backcolor = new EnableDisableAppearance();
[Description("The text color of the component"), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public new EnableDisableAppearance ForeColor { get { return forecolor; } set { forecolor = value; SetAppearance(); } }
private EnableDisableAppearance forecolor = new EnableDisableAppearance();
public new bool Enabled { get { return enabled; } set { enabled = value; SetAppearance(); } }
private bool enabled = true;
private void SetAppearance()
{
base.BackColor = (enabled ? backcolor.Enabled : backcolor.Disabled);
base.ForeColor = (enabled ? forecolor.Enabled : forecolor.Disabled);
}
}
这是Attribute和TypeConverter类:
[TypeConverter(typeof(EnableDisableAppearanceTypeConverter))]
public class EnableDisableAppearance : Attribute
{
public EnableDisableAppearance()
{
}
public EnableDisableAppearance(Color enabled, Color disabled)
{
this.enabled = enabled;
this.disabled = disabled;
}
[Description("Color when enabled"), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), DefaultValue(typeof(Color), "LightGray")]
public Color Enabled { get { return enabled; } set { enabled = value; } }
private Color enabled = new Color();
[Description("Color when disabled"), Category("Appearance"), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), DefaultValue(typeof(Color), "DarkGray")]
public Color Disabled { get { return disabled; } set { disabled = value; } }
private Color disabled = new Color();
public override string ToString()
{
string ret = "";
if (enabled.IsKnownColor) { ret += "Enabled " + enabled.ToString(); }
else { ret += string.Format("Enabled [{0}, {1}, {2}]", enabled.R.ToString(), enabled.G.ToString(), enabled.B.ToString()); }
if (disabled.IsKnownColor) { ret += ", Disabled " + disabled.ToString(); }
else { ret += string.Format(", Disabled [{0}, {1}, {2}]", disabled.R.ToString(), disabled.G.ToString(), disabled.B.ToString()); }
return ret.Replace("Color ", "");
}
}
public class EnableDisableAppearanceTypeConverter : TypeConverter
{
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true; //base.GetPropertiesSupported(context);
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return TypeDescriptor.GetProperties(typeof(EnableDisableAppearance));
}
}
答案 0 :(得分:1)
ZButton
中Enabled
或Disabled
属性发生变化时,您需要通知EnableDisableAppearance
。为此,添加一个事件并在属性更改时将其引发。仅显示其他代码:
public class EnableDisableAppearance : Attribute
{
public event EventHandler AppearanceChanged;
protected virtual void OnAppearanceChanged()
{
AppearanceChanged?.Invoke(this, EventArgs.Empty);
}
[Description("Color when enabled"), ...]
public Color Enabled
{
get { return enabled; }
set {
if (value != enabled) {
enabled = value;
OnAppearanceChanged();
}
}
}
// Do the same in the Disabled property...
...
}
ZButton
必须小心地附加和分离事件
public partial class ZButton : Button
{
private void Backcolor_AppearanceChanged(object sender, EventArgs e)
{
SetAppearance();
}
[Description("The background color ...]
public new EnableDisableAppearance BackColor
{
get { return backcolor; }
set {
if (value != backcolor) {
if (backcolor != null) {
// Detach event handler from old appearance object
backcolor.AppearanceChanged -= Backcolor_AppearanceChanged;
}
backcolor = value;
SetAppearance();
if (backcolor != null) {
// Attach event handler to new appearance object
backcolor.AppearanceChanged += Backcolor_AppearanceChanged;
}
}
}
}
// Same for ForeColor...
...
}
添加一些空检查以确保安全
private void SetAppearance()
{
if (backcolor != null)
base.BackColor = enabled ? backcolor.Enabled : backcolor.Disabled;
if (forecolor != null)
base.ForeColor = enabled ? forecolor.Enabled : forecolor.Disabled;
}