Winforms TabControl 导致 UserControl 的虚假 Paint 事件

发布于 2024-08-26 09:58:42 字数 4613 浏览 5 评论 0原文

对于我们的项目,我们编写了一个用于绘图的 WinForms UserControl。

当我们的控件位于 TabControl 中时,我们会看到一些奇怪的行为 - 我们的控件不断触发 Paint 事件,即使用户绝对没有任何活动。

我们只在 TabControl 中看到这一点。当我们将控件放置在其他容器(例如表单或拆分器)中时,Paint 仅在您期望的情况下才会触发,例如首次显示控件时等。

任何人都可以建议为什么会发生这种情况吗?

这是我们控件的 Paint 处理程序中断点的堆栈跟踪,如果有帮助的话。我们的控件是 BaseGraphXY,它位于 TabControl 上,而 TabControl 位于一些嵌套的 SplitContainer 上。对格式感到抱歉 - 由于某种原因无法让 SO 编辑器停止换行。

OverlordFrontEnd.exe!OverlordFrontEnd.MainForm.graphControl_Paint(object sender =  BI_BaseGraphXY.BaseGraphXY}, System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1031,Height=408}}) Line 422 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.OnPaint(System.Windows.Forms.PaintEventArgs e) + 0x73 bytes   
BI_AppCore.dll!BI_BaseGraphXY.BaseGraphXY.OnPaint(System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1031,Height=408}}) Line 377 + 0xb bytes   C#
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintTransparentBackground(System.Windows.Forms.PaintEventArgs e, System.Drawing.Rectangle rectangle, System.Drawing.Region transparentRegion = null) + 0x16c bytes   
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintBackground(System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1029,Height=406}}, System.Drawing.Rectangle rectangle, System.Drawing.Color backColor, System.Drawing.Point scrollOffset) + 0xbc bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintBackground(System.Windows.Forms.PaintEventArgs e, System.Drawing.Rectangle rectangle) + 0x63 bytes   
System.Windows.Forms.dll!System.Windows.Forms.Control.OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent) + 0x59 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1029,Height=406}}, short layer, bool disposeEventArgs = false) + 0x74 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.WmPaint(ref System.Windows.Forms.Message m) + 0x1ba bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x33e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes  
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg = 15, System.IntPtr wparam, System.IntPtr lparam) + 0x5a bytes  
[Native to Managed Transition]  
[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x24e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.WinFormsAppContext}) + 0x177 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x18 bytes 
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() + 0x81 bytes    
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xef bytes   
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x2c0 bytes 
OverlordFrontEnd.exe!OverlordFrontEnd.Program.Main() Line 36 + 0x10 bytes   C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x3a bytes    
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes  
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes   
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   

For our project, we've written a WinForms UserControl for graphing.

We're seeing some strange behavior when our control is sited in a TabControl - our control continuously fires Paint events, even when there is absolutely no activity by the user.

We only see this in the TabControl. When we site our control in other containers such as Forms or Splitters, Paint is only fired when you'd expect e.g. when the control is first displayed, etc.

Can anyone suggest why this might be happening?

Here's a stack trace from a breakpoint in our control's Paint handler, if that's any help. Our control is BaseGraphXY, which is sited on a TabControl, which is sited on some nested SplitContainers. Sorry about the formatting - couldn't get the SO editor to stop wrapping, for some reason.

OverlordFrontEnd.exe!OverlordFrontEnd.MainForm.graphControl_Paint(object sender =  BI_BaseGraphXY.BaseGraphXY}, System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1031,Height=408}}) Line 422 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.OnPaint(System.Windows.Forms.PaintEventArgs e) + 0x73 bytes   
BI_AppCore.dll!BI_BaseGraphXY.BaseGraphXY.OnPaint(System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1031,Height=408}}) Line 377 + 0xb bytes   C#
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintTransparentBackground(System.Windows.Forms.PaintEventArgs e, System.Drawing.Rectangle rectangle, System.Drawing.Region transparentRegion = null) + 0x16c bytes   
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintBackground(System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1029,Height=406}}, System.Drawing.Rectangle rectangle, System.Drawing.Color backColor, System.Drawing.Point scrollOffset) + 0xbc bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintBackground(System.Windows.Forms.PaintEventArgs e, System.Drawing.Rectangle rectangle) + 0x63 bytes   
System.Windows.Forms.dll!System.Windows.Forms.Control.OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent) + 0x59 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs e = {ClipRectangle = {X=0,Y=0,Width=1029,Height=406}}, short layer, bool disposeEventArgs = false) + 0x74 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.WmPaint(ref System.Windows.Forms.Message m) + 0x1ba bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x33e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes  
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg = 15, System.IntPtr wparam, System.IntPtr lparam) + 0x5a bytes  
[Native to Managed Transition]  
[Managed to Native Transition]  
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x24e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.WinFormsAppContext}) + 0x177 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x18 bytes 
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() + 0x81 bytes    
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xef bytes   
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x2c0 bytes 
OverlordFrontEnd.exe!OverlordFrontEnd.Program.Main() Line 36 + 0x10 bytes   C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x3a bytes    
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes  
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes   
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

调妓 2024-09-02 09:58:42

选项卡控件确实有一些怪癖,尝试修改 SetStyle:

Me.SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.DoubleBuffer Or ControlStyles.Selectable Or ControlStyles.ResizeRedraw, True)

Tab Control does have some quirks, try tinkering with SetStyle:

Me.SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.DoubleBuffer Or ControlStyles.Selectable Or ControlStyles.ResizeRedraw, True)

微凉徒眸意 2024-09-02 09:58:42

我的同事找到了解决该问题的方法:

图形控件的问题是 BackColor 属性默认为 System.Drawing.Color.Transparent。这导致了一种消息的“反馈循环”。我想它应该这样工作?不管怎样,我更改了构造函数以使用 System.Drawing.SystemColors.ControlLightLight 作为默认 BackColor 属性。这似乎抑制了额外的图形绘制。

My co-worker has found a workaround for the problem:

The problem with the graph control was that the BackColor property was defaulting to System.Drawing.Color.Transparent. This caused a kind of a "feedback loop" of messages. I guess that it is supposed to work this way? Anway, I changed the constructor to use System.Drawing.SystemColors.ControlLightLight as the default BackColor property. This seems to suppress the extra graph painting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文