【发布时间】:2011-10-05 08:59:30
【问题描述】:
如何检测控件是否对用户可见?我有一个显示应用程序状态的控件,并且我希望它仅在用户看到它时才更新(它的值要更新,例如,增加进度条的值,或更改标签的 Text 属性)。如果用户已最小化包含此控件的表单,或者另一个表单与此控件重叠,则无需更新它。如果控件不可见,我只是不想进行额外的计算。 另外,如何检测隐藏/显示此控件的事件?
【问题讨论】:
标签: c# .net winforms controls visibility
如何检测控件是否对用户可见?我有一个显示应用程序状态的控件,并且我希望它仅在用户看到它时才更新(它的值要更新,例如,增加进度条的值,或更改标签的 Text 属性)。如果用户已最小化包含此控件的表单,或者另一个表单与此控件重叠,则无需更新它。如果控件不可见,我只是不想进行额外的计算。 另外,如何检测隐藏/显示此控件的事件?
【问题讨论】:
标签: c# .net winforms controls visibility
这似乎是经常被问到的主题之一,并且有许多可能的解决方案,具体取决于上下文。
首先,作为参考,一些链接指向我在研究期间偶然发现的旧讨论:
起始位置: 用于异构系统的 IDE,具有大量不同的硬件和许多不同的传输层,其中一些非常慢。一项功能是在编辑器中显示远程硬件的内存值。一个典型的用例是打开超过 20 个编辑器,每个编辑器显示 1 到 100 个不同的值。
由于传输层的带宽有限,我一直在寻找一种解决方案来“优先考虑”数据采集。
(部分)解决方案: 一个可见性跟踪器,它基本上为控件本身和每个祖先控件管理一个专门的适配器。适配器根据祖先类型处理可见性,即。对于控件,它只是实例。可见,对于 TabPage,我检查选择了哪个页面,... 然后,经理的内务管理只是跟踪所有祖先的父级更改,以便跟踪正确的可见性。
【讨论】:
了解表单是否具有焦点或最小化是您最好的选择,但我不确定是否适用于所有情况。一般来说,无论用户是否注意,我都会更新,除非需要大量周期才能将信息发送到表单,我对此表示怀疑。在应用程序中设置条件位只会增加另一个出错的地方。
让我们来看看这个。最小化形式是一回事。如果表单被最小化,你就知道用户甚至没有看它。但是,如果另一个表单在前面,那么你要检查表单是否有焦点。这里的问题是一个人可以在另一半输入单词时使用一半屏幕观看。 Word 具有焦点,因此表单不会更新,这不是您的意图。如果您在应用程序中创建另一个表单,也会发生同样的情况。更新不再具有焦点。
Windows 中没有神奇的“用户是否在看我”属性。
【讨论】:
这从来没有必要。当窗口不可见时,Windows 不会生成 Paint 事件。如果您自己实现了绘画,请确保仅在 Paint 事件中执行此操作,并且如果有重新绘画的原因,则调用 Invalidate()。
【讨论】:
Paint 事件中进行额外计算。该代码不会执行,除非该控件在屏幕上对用户可见。
状态多久更改一次?最好在状态更改时更新状态指示器,而不用担心可见性。假设状态平均每 5 分钟更改一次。当状态改变时窗口/控件可能不可见,但在下一次状态更新之前很容易变得可见。在这种情况下,状态指示器会一直出错,直到下次更新,因为您避免更改指示器。除非更新状态指示器非常昂贵,否则最好不要尝试预测用户会做什么。
查看其他 cmets 后编辑:
我认为您可以通过确定用于检测/通知状态变化的模型而不是按需计算来实现更好的效率改进。您可能需要权衡状态更改的频率与控件可见性更改的频率。
【讨论】:
【讨论】: