繁体   English   中英

Invalidate()自定义控件对每个属性的更改?

[英]Invalidate() custom control on every property change?

我正在开发一个自定义的winforms控件,该控件公开了许多影响控件外观的属性(背景,文本和悬停,单击以及图标等不同状态的不同颜色)。 对这些属性之一的更改使得必须重新绘制,因此目前每个属性都有一个getter和setter,该setter调用Invalidate() 这对代码非常烦人,并且如果一次更改多个属性,即使最后一个重绘就足够了,但每个属性都会导致重绘。

我有以下想法,但我不知道它们是否可行或如何实现:

  1. 缓存属性更改几毫秒,然后Invalidate()
  2. 使用某种反射来检测调用方是否要在下一行中更改另一个属性,如果是,则延迟对Invalidate()的调用
  3. 可能需要重绘的属性之前有一些属性,或者是所有此类属性的列表,这些属性在编译时已扩展到getter / setter

如果这些想法有意义/可行,您能给我一些建议,并指出如何实施它们吗?

请注意,我将远离选项2。关于选项1,以某种方式,属性更改已由系统缓存,只有UI线程返回到处理消息后,它才会重绘。 至于选项3,似乎有些牵连。

但是要回答您的问题,最简单的方法是在您的班级中创建一个在给定时间间隔触发的计时器。 然后使用bool,如果为true,则计时器的Tick处理程序将调用Invalidate()并将其设置回false。 最后,制作一个将代替Invalidate的方法,该方法会将布尔值标记为true。

在您的情况下,可能存在一些我不知道的危险,但这是一个示例:

public class InvalidationUserControl : UserControl
{
   bool _isInvalid = false;
   int _data;
   Timer t = new Timer();

   public InvalidationUserControl()
   {
      InitializeComponent();
      t.Interval = 100;  // Go ahead an play with this number, the higher
                         // it is the greater the latency
      t.Tick += t_Tick;
      t.Start();
   }

   void InvalidateIfNeeded()
   {
      _isInvalid = true;
   }

   void t_Tick(object sender, EventArgs e)
   {
      if (_isInvalid)
      {
          _isInvalid = false;
          Invalidate();
      }
   }

   public int Data
   {
       get { return _data; }
       set
       {
           _data = value;
           InvalidateIfNeeded();
       }
   }
}

可能会有更好的方法,但这是一种快速的解决方案,可以完全按照您需要的方式工作。

您所要做的就是调用InvalidateIfNeeded()而不是Invalidate(),它应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM