[英]Is there a way to respond to a change of System colors at design time?
I've got a usercontrol (derived from ContainerControl) which I'm filling using a gradient.我有一个使用渐变填充的用户控件(源自 ContainerControl)。 The first gradient color may or may not be a system color, like
SystemColors.Highlight
.第一个渐变颜色可能是也可能不是系统颜色,例如
SystemColors.Highlight
。 The second gradient color is derived from the first one, by means of ControlPaint.Light(firstColor)
or something similar.第二个渐变颜色是通过
ControlPaint.Light(firstColor)
或类似的方法从第一个渐变颜色派生的。
I can easily handle changing system colors at runtime by overriding OnSystemColorsChanged
, and it works without any trouble.我可以通过覆盖 OnSystemColorsChanged 在运行时轻松处理更改系统
OnSystemColorsChanged
,并且它可以毫无问题地工作。 But if the control is placed on a form at design time, and then the system colors are changed, the second color stays the same, probably due to OnSystemColorsChanged
not being called at design time.但是,如果在设计时将控件放置在窗体上,然后系统 colors 发生更改,则第二种颜色保持不变,可能是由于在设计时未调用
OnSystemColorsChanged
。
I can reset the second color manually since I provide ShouldSerialize- and Reset- methods for the second color property, and therefore the default value for that property changes accordingly when the system color changes.我可以手动重置第二种颜色,因为我为第二种颜色属性提供了 ShouldSerialize- 和 Reset- 方法,因此当系统颜色发生变化时,该属性的默认值也会相应变化。
So, is there any way to catch a system color change at design time?那么,有没有办法在设计时捕捉系统颜色的变化?
Edit:编辑:
Here's a minimized code sample:这是一个最小化的代码示例:
public class Test : ContainerControl
{
public Test()
{
ResetColor1();
ResetColor2();
}
private bool _resetColor2;
// Color 1 stuff
private Color _color1 = Color.Empty;
public System.Drawing.Color Color1
{
get { return _color1; }
set
{
_resetColor2 = !ShouldSerializeColor2();
_color1 = value;
if (_resetColor2)
ResetColor2();
Invalidate();
}
}
// Defaults Color 1
private Color DefaultColor1 { get { return SystemColors.Highlight; } }
public bool ShouldSerializeColor1()
{
return !Color1.Equals(Color.Empty) && !Color1.Equals(DefaultColor1);
}
public void ResetColor1()
{
Color1 = DefaultColor1;
}
// Color 2 stuff
private Color _color2 = Color.Empty;
public System.Drawing.Color Color2
{
get { return _color2; }
set
{
_color2 = value;
Invalidate();
}
}
private Color DefaultColor2 { get { return ControlPaint.Light(Color1); } }
public bool ShouldSerializeColor2()
{
return !Color2.Equals(DefaultColor2);
}
public void ResetColor2()
{
Color2 = DefaultColor2;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (LinearGradientBrush b = new LinearGradientBrush(ClientRectangle, Color1, Color2, LinearGradientMode.ForwardDiagonal))
e.Graphics.FillRectangle(b, this.ClientRectangle);
}
protected override void OnSystemColorsChanged(EventArgs e)
{
base.OnSystemColorsChanged(e);
if (_resetColor2)
ResetColor2();
}
}
If you put this control onto a form, this code will do the following:如果将此控件放在窗体上,此代码将执行以下操作:
Default Color1 to SystemColors.Highlight默认 Color1 为 SystemColors.Highlight
Default Color2 to a lighter color默认 Color2 为较浅的颜色
If Color2 is not changed manually, it will automatically derive from Color1如果不手动更改 Color2,它将自动从 Color1 派生
If system colors change at runtime, Color1 and Color2 will both change如果系统 colors 在运行时发生变化,Color1 和 Color2 都会发生变化
If system colors change at design time, only Color1 will change如果系统 colors 在设计时更改,则只有 Color1 会更改
You can subscribe to the SystemEvents.DisplaySettingsChanged event, I believe.我相信您可以订阅SystemEvents.DisplaySettingsChanged事件。
I wouldn't be too surprised if the event is suppressed in design mode, SystemEvents are tricky because they are static events.如果事件在设计模式下被抑制,我不会太惊讶,SystemEvents 很棘手,因为它们是 static 事件。 Solve your problem by setting a bool flag in the property setter for Color2 to indicate that it matches the default color.
通过在 Color2 的属性设置器中设置一个布尔标志来指示它与默认颜色匹配,从而解决您的问题。 Always use ControlPaint.Light() when the flag is set.
设置标志时始终使用 ControlPaint.Light()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.