Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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# 我如何知道MDI子窗体在视觉上发生了更改?_C#_Winforms_Winapi_Mdi - Fatal编程技术网

C# 我如何知道MDI子窗体在视觉上发生了更改?

C# 我如何知道MDI子窗体在视觉上发生了更改?,c#,winforms,winapi,mdi,C#,Winforms,Winapi,Mdi,我用C#编写了MDI WinForms应用程序。通常只有一个MDI子窗体可见,其他所有窗体都在后台。子表单内容可能偶尔在后台发生更改(例如,web浏览器控件可能显示每N秒动态更改一次的页面,随着时间的推移,图表控件中会充满数据) 我想在用户将鼠标悬停在主窗体的工具栏上或单击工具栏中的特殊按钮时显示子窗体的小预览。我可以成功地使用PrintWindow函数(如上所述)制作子MDI表单的屏幕截图。这甚至适用于非活动子窗体。唯一的问题是,拍摄每个屏幕截图可能需要很长的时间(大约100-120毫秒),可

我用C#编写了MDI WinForms应用程序。通常只有一个MDI子窗体可见,其他所有窗体都在后台。子表单内容可能偶尔在后台发生更改(例如,web浏览器控件可能显示每N秒动态更改一次的页面,随着时间的推移,图表控件中会充满数据)

我想在用户将鼠标悬停在主窗体的工具栏上或单击工具栏中的特殊按钮时显示子窗体的小预览。我可以成功地使用PrintWindow函数(如上所述)制作子MDI表单的屏幕截图。这甚至适用于非活动子窗体。唯一的问题是,拍摄每个屏幕截图可能需要很长的时间(大约100-120毫秒),可能是因为表单的复杂结构,因此如果我在想要显示预览之前拍摄屏幕截图,那么这会造成明显的延迟,尤其是当有很多子表单(例如10-15)时

我想优化这一点,并重新创建截图,只有当它是真正需要的。这就是我的意思。最初我会为所有表单创建屏幕截图,将它们存储在“缓存”中并显示预览。稍后,当我需要再次创建预览时,我想以某种方式确定MDI表单的可视内容已更改(或更改待定),并仅在这种情况下重新创建屏幕截图,否则使用“缓存”屏幕截图

我试图通过重写子表单类的WndProc函数并查找诸如WM_PAINT或WM_SETREDRAW之类的消息来实现这一点。但当我记录所有消息时,我既看不到WM_PAINT,也看不到WM_SETREDRAW,即使表单处于活动状态(在前台),并且表单上的web浏览器控件不断更新其页面。这些事件可能会直接发送到窗体的控件,但不会发送到窗体本身

我不想遍历每个表单并连接到所有控件的“已更改”事件,因为它们都非常不同,并且不是所有控件都有这样的通知事件

我猜每个控件在想要更改其视觉表示时都会向操作系统发送一些通知,以强制进行自重绘那么,有没有办法从MDI子窗体中的任何控件检测到此类通知?

更新:
我发现WinAPI函数应该返回一个需要重新绘制的矩形。我认为,如果它返回非空矩形,则意味着需要更新屏幕截图。我试图在调用PrintWindow之前调用它,但它总是返回空矩形。

那么,在后台更改表单内容的东西应该知道什么时候会发生这种情况,对吗?您可以引发一个事件,在Manager类中订阅它,它应该在不同的线程中处理整个事件,这样在创建位图时MDI父级就不会断断续续(顺便说一句,创建缩略图需要100-200毫秒)。是的,但一般来说,这意味着我必须从每个表单中的每个组件订阅此类通知,如果我添加了一些新表单,不要忘记这样做。可行,但不是很优雅。这就是为什么我建议上经理课。由于要重新创建整个表单的缩略图,因此不需要每个受影响的控件都通知更改。你只需要知道有些事情已经改变了。不管是什么,都需要重新绘制缩略图。由于您没有指定导致UI中发生更改的原因,因此无法说明具体的原因。关键是,这是一个程序造成的。此过程应提供通知。所谓“管理器”类,是指自行编写的类,还是指dotNet framework中的标准类?这取决于您在实践中所做的工作。这些控件是否绑定到数据源?您可以使用BindingSource提供的通知。或者有一个实现
INotifyPropertyChange
的类。或者仅仅是一个类,它知道一些事情即将发生,这些事情将影响UI并相应地采取行动。此类不应干扰/交互UI(与窗体和主线程分离),并在不同的线程中执行其进程。作为松散术语的线程。你有CPU限制的工作,所以可能是任务。那么,在后台改变表单内容的东西应该知道什么时候会发生,对吗?您可以引发一个事件,在Manager类中订阅它,它应该在不同的线程中处理整个事件,这样在创建位图时MDI父级就不会断断续续(顺便说一句,创建缩略图需要100-200毫秒)。是的,但一般来说,这意味着我必须从每个表单中的每个组件订阅此类通知,如果我添加了一些新表单,不要忘记这样做。可行,但不是很优雅。这就是为什么我建议上经理课。由于要重新创建整个表单的缩略图,因此不需要每个受影响的控件都通知更改。你只需要知道有些事情已经改变了。不管是什么,都需要重新绘制缩略图。由于您没有指定导致UI中发生更改的原因,因此无法说明具体的原因。关键是,这是一个程序造成的。此过程应提供通知。所谓“管理器”类,是指自行编写的类,还是指dotNet framework中的标准类?这取决于您在实践中所做的工作。这些控件是否绑定到数据源?您可以使用BindingSource提供的通知。或者有一个实现
INotifyPropertyChange
的类。或者仅仅是一个类,它知道一些事情即将发生,这些事情将影响UI并相应地采取行动。此类不应干扰/交互UI(与窗体和主线程分离),并在不同的线程中执行其进程。作为松散术语的线程。您有CPU限制的工作,所以可能是任务。