Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有一种方法可以在设计时响应系统颜色的变化?_C#_User Controls_Systemcolors - Fatal编程技术网

C# 是否有一种方法可以在设计时响应系统颜色的变化?

C# 是否有一种方法可以在设计时响应系统颜色的变化?,c#,user-controls,systemcolors,C#,User Controls,Systemcolors,我有一个用户控件(来自ContainerControl),我正在使用渐变填充它。第一种渐变颜色可能是系统颜色,也可能不是系统颜色,如SystemColors.Highlight。 第二种渐变色是通过ControlPaint.Light(firstColor)或类似方法从第一种渐变色派生而来的 我可以通过覆盖OnSystemColorsChanged在运行时轻松处理更改系统颜色的问题,而且它工作起来没有任何问题。但是,如果在设计时将控件放置在表单上,然后更改系统颜色,则第二种颜色将保持不变,这可能

我有一个用户控件(来自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();
}
}
如果将此控件放到窗体上,此代码将执行以下操作:

  • 默认颜色1到系统颜色。高亮显示

  • 默认颜色2为较浅的颜色

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

  • 如果系统颜色在运行时更改,则Color1和Color2都将更改

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


我相信您可以订阅该事件。

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

我们能看到一些代码吗?我想我有可能找到解决方案的原因,但我想确定一下。结束,谢谢你的指点。看起来好像
SystemEvents.UserPreferenceChanged
在设计模式下工作。我现在需要对此进行广泛的测试…您当时就在那里,
SystemEvents.DisplaySettingsChanged
被抑制
SystemEvents.UserPreferenceChanged
似乎有效,但您的方法似乎更容易处理。我将检查这两种方法,然后选择更简单的方法。