2013-04-22 100 views
4

我有一个树视图和基于TreeView的项目,我有右侧的列表视图。所以几乎UI是我们的Windows资源管理器的外观。所以现在我面临的问题是,当我从列表视图中删除大量的对象来到右侧时,左侧的树视图变成部分画(我可以说小部分)。当我从VS IDE获得CLR excpetion时,它指向line sampletree.EndUpdate();除了内存不足之外。当我加入的ListView一切下一个项目都正常我的意思是树状完全画 异常我得到是.net中的内存异常winform treeview

System.OutOfMemoryException occurred 
    Message=Out of memory. 
    Source=System.Drawing 
    StackTrace: 
     at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc) 
     at System.Drawing.Font.ToLogFont(Object logFont) 
     at System.Drawing.Font.ToHfont() 
     at System.Windows.Forms.Control.FontHandleWrapper..ctor(Font font) 
     at System.Windows.Forms.OwnerDrawPropertyBag.get_FontHandle() 
     at System.Windows.Forms.TreeView.CustomDraw(Message& m) 
     at System.Windows.Forms.TreeView.WmNotify(Message& m) 
     at System.Windows.Forms.TreeView.WndProc(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
     at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m) 
     at System.Windows.Forms.Control.WmNotify(Message& m) 
     at System.Windows.Forms.Control.WndProc(Message& m) 
     at System.Windows.Forms.ScrollableControl.WndProc(Message& m) 
     at System.Windows.Forms.UserControl.WndProc(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
     at System.Windows.Forms.NativeWindow.DefWndProc(Message& m) 
     at System.Windows.Forms.Control.DefWndProc(Message& m) 
     at System.Windows.Forms.Control.WndProc(Message& m) 
     at System.Windows.Forms.TreeView.WndProc(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam) 
     at System.Windows.Forms.Control.EndUpdateInternal(Boolean invalidate) 
     at System.Windows.Forms.TreeView.EndUpdate() 

你有我为什么我的TreeView的是只涂一个samll一部分,并连续修改油漆充分的任何想法?代码片段显示belowe

if((values != null) && 
     (values .OverallState != ToBeDeleted) && 
     (values .OverallState != .Deleted)) 
    { 
     TreeView tree = this.TreeView; 
     if(tree != null) 
     { 
      tree.BeginUpdate(); 
     } 
     TryUpdate(); 
     TryPopulate(); 
     if(tree != null) 
     { 
      tree.EndUpdate(); // here exception coming 
     } 
    } 

UPDATE 我使用的字体像这样

case State.Modified: 
        NodeFont = new Font(TreeView.Font, FontStyle.Bold); 
break; 

这是否漏水GDI资源使

+0

做的winform树视图有任何已知的问题,或者任何索引变成-1? – vettori 2013-04-22 13:46:52

+0

同样的问题在这里。任务管理器显示该进程创建了10,000个GDI字体句柄(然后崩溃,最大值为10,000)。只有当我同时创建很多节点时才会发生这种情况。 – dacap 2013-07-11 17:10:38

回答

2

这种崩溃的常见原因的任何问题。这通常是由于忘记在任何System.Drawing类对象上调用Dispose()方法造成的。通常情况下,垃圾收集器会在你之后清理,但是,特别是当你使用ownerdraw时,它可能无法经常运行以避免麻烦。当你消耗了10000个GDI对象时,Windows会在你的程序中插入这个插件,结果是kaboom。

您可以从任务管理器轻松地诊断此问题。查看+选择列并勾选句柄,USER对象和GDI对象。在使用过程中,观察您的流程添加的列。稳步攀升的数字预示着OOM Kaboom。

首先查看您的DrawNode事件处理函数,因为它可能会被频繁调用。但也可能由其他绘画代码引起。确保您使用语句创建图形,笔,画笔,字体等绘图对象,并使用声明,以确保它们在使用后处置。你从任务管理器获得的诊断告诉你什么时候你在前面。

+0

你可能是正确的,我现在想知道的是当问题出现的时候(treeview切割一半)删除lot对象后,再次添加单个对象时,一切都会变得正常,原因是什么? – vettori 2013-04-22 18:23:33

+0

想知道这一点是毫无意义的,明显更少的数据会导致你忘记处理的句柄更少。使用事实,任务管理器告诉你什么? – 2013-04-22 18:30:09

+0

任务管理器显示Handles,USER对象和GDI对象的计数增加,但并不是连续的,它停止了某些值,并开始减少到一些值。我修改了我的问题。当使用字体我didtn使用使用语句 – vettori 2013-04-22 18:35:54

1

我刚碰到同样的问题。它似乎只发生在晚于XP的Windows系统中,并且当我删除BeginUpdate()EndUpdate()调用时,它不会发生。

因此,作为一种解决方法,我会说尝试删除BeginUpdate()EndUpdate()调用。这确实意味着在更新节点时可能会出现一些视觉障碍,但从正面来看,它不会崩溃。这无疑是一场净胜。

我在MSDN/Connect上找不到任何解决此问题的问题,我现在没有时间将自包含的测试用例组合在一起,但我确实认为这是处理批量更新中的错误在更高版本的Windows中使用TreeViews。

+0

另外,如果你只是用'myTreeView.Visible = false'代替'BeginUpdate()',用'myTreeView.Visible = true'代替'EndUpdate()' - 你可以避免所有的屏幕闪烁,并且不会遇到bug。 (这似乎也有相当不错的表现。) – 2016-02-12 14:45:20