有没有办法在设计时响应系统颜色的变化?

时间:2011-05-04 11:53:35

标签: c# user-controls systemcolors

我有一个usercontrol(派生自ContainerControl),我正在使用渐变填充。第一种渐变颜色可能是也可能不是系统颜色,如SystemColors.Highlight。 第二种渐变颜色来自第一种颜色,通过ControlPaint.Light(firstColor)或类似的东西。

我可以通过覆盖OnSystemColorsChanged轻松处理在运行时更改系统颜色,并且它可以正常工作。但是如果在设计时将控件放在窗体上,然后系统颜色发生变化,则第二种颜色保持不变,可能是由于在设计时没有调用OnSystemColorsChanged

我可以手动重置第二种颜色,因为我为第二种颜色属性提供了ShouldSerialize-和Reset-方法,因此当系统颜色发生变化时,该属性的默认值也会相应地改变。

那么,有没有办法在设计时捕捉系统颜色变化?

修改

这是一个最小化的代码示例:

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();
}
}

如果将此控件放在表单上,​​此代码将执行以下操作:

  • 默认Color1到SystemColors.Highlight

  • 默认Color2为浅色

  • 如果不手动更改Color2,它将自动从Color1派生

  • 如果系统颜色在运行时发生变化,Color1和Color2都会改变

  • 如果系统颜色在设计时更改,则只有Color1会更改

2 个答案:

答案 0 :(得分:1)

我相信您可以订阅SystemEvents.DisplaySettingsChanged活动。

答案 1 :(得分:1)

如果事件在设计模式中被抑制,我不会太惊讶,SystemEvents很棘手,因为它们是静态事件。通过在Color2的属性设置器中设置bool标志来解决您的问题,以指示它与默认颜色匹配。设置标志时始终使用ControlPaint.Light()。