对每个属性更改使自定义控件无效()



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

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

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

如果这些想法有意义/可能,你能给我一些建议吗?并告诉我如何实施它们?

请注意,我将远离选项2。关于选项1,在某种程度上,属性更改已经被系统缓存,只有当UI线程返回处理消息时,它才会重新绘制。至于备选方案3,似乎有点涉及。

但在回答你的问题时,最简单的方法是在你的课上创建一个定时器,在给定的时间间隔内启动。然后有一个bool,如果它是true,计时器的Tick处理程序将调用Invalidate()并将其设置回false。最后,制作一个方法,用它代替Invalidate,将bool标记为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();
       }
   }
}

可能有更好的方法,但这是一个快速的解决方案,可能正是你需要的方式

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

最新更新