2013-01-03 32 views
6

这是一个奇怪的。我有一个DataGridView。我将DataSource设置为List,其中包含我自己的自定义类的对象。列表中约有50,000件物品。我定义了所有希望在Designer中可见的列,并将AutoGenerateColumns设置为false。StackOverflowException与DataGridView

只要我将DataSource设置到我的列表中,它就会立即填充正确。我可以上下滚动,选择不同的行。一切都很好。但是,当我滚动所有的方式下来,然后让含有DataGridView失去焦点都冻结起来,而堆栈溢出这样经过短暂的窗口:

System.Drawing.dll!System.Drawing.SafeNativeMethods.Gdip.GdipDeleteGraphics(System.Runtime.InteropServices.HandleRef graphics) + 0x2a bytes 
    System.Drawing.dll!System.Drawing.Graphics.Dispose(bool disposing) + 0x56 bytes 
    System.Drawing.dll!System.Drawing.Graphics.Dispose() + 0x12 bytes 
    System.Drawing.dll!System.Drawing.Font.GetHeight() + 0xc8 bytes 
    System.Drawing.dll!System.Drawing.Font.Height.get() + 0xb bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRow() + 0x44 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.Clone() + 0x44 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRowCollection.this[int].get(int index) + 0xa8 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridView.DataGridViewAccessibleObject.GetChild(int index) + 0xbd bytes  
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x76 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get() + 0x83 bytes 
    ... 

出于某种原因,DataGridViewRow.DataGridViewRowAccessibleObject.Bounds.get()方法本身调用到遗忘。整个堆栈对我来说似乎很奇怪。为什么Font.Height.get()曾经打电话给DataGridViewRow

编辑:

我被问了一些代码。这是设计师生成的代码为DataGridView其列:

// 
    // dataGridView 
    // 
    this.dataGridView.AllowUserToAddRows = false; 
    this.dataGridView.AllowUserToDeleteRows = false; 
    this.dataGridView.AllowUserToOrderColumns = true; 
    this.dataGridView.AllowUserToResizeRows = false; 
    this.dataGridView.BackgroundColor = System.Drawing.SystemColors.Window; 
    this.dataGridView.BorderStyle = System.Windows.Forms.BorderStyle.None; 
    this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 
    this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 
    this.Date, 
    this.Type, 
    this.Job, 
    this.Mix, 
    this.Entry}); 
    this.dataGridView.Location = new System.Drawing.Point(8, 96); 
    this.dataGridView.Name = "dataGridView"; 
    this.dataGridView.ReadOnly = true; 
    this.dataGridView.RowHeadersVisible = false; 
    this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 
    this.dataGridView.Size = new System.Drawing.Size(1152, 504); 
    this.dataGridView.TabIndex = 10; 
    this.dataGridView.SelectionChanged += new System.EventHandler(this.dataGridView_SelectionChanged); 
    // 
    // Date 
    // 
    this.Date.DataPropertyName = "FormattedTime"; 
    this.Date.HeaderText = "Date/Time"; 
    this.Date.Name = "Date"; 
    this.Date.ReadOnly = true; 
    // 
    // Type 
    // 
    this.Type.DataPropertyName = "FormattedType"; 
    this.Type.FillWeight = 60F; 
    this.Type.HeaderText = "Type"; 
    this.Type.Name = "Type"; 
    this.Type.ReadOnly = true; 
    this.Type.Width = 60; 
    // 
    // Job 
    // 
    this.Job.DataPropertyName = "Job"; 
    this.Job.FillWeight = 80F; 
    this.Job.HeaderText = "Job No."; 
    this.Job.Name = "Job"; 
    this.Job.ReadOnly = true; 
    this.Job.Width = 80; 
    // 
    // Mix 
    // 
    this.Mix.DataPropertyName = "Mix"; 
    this.Mix.FillWeight = 80F; 
    this.Mix.HeaderText = "Mix No."; 
    this.Mix.Name = "Mix"; 
    this.Mix.ReadOnly = true; 
    this.Mix.Width = 80; 
    // 
    // Entry 
    // 
    this.Entry.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 
    this.Entry.DataPropertyName = "FormattedSummary"; 
    this.Entry.HeaderText = "Entry"; 
    this.Entry.Name = "Entry"; 
    this.Entry.ReadOnly = true; 

当开始的时间,来填充网格视图,我只是做了:

dataGridView.DataSource = myList; 
+0

什么是你的代码? –

+0

我用一些代码更新了我的问题。谢谢。 –

回答

8

修复

没有锁定在这个时候知道。

解决方法

禁用从控制面板中的服务面板Tablet PC输入服务(又名tabtip.exe)。

详细信息

几个星期前,我联系了Microsoft开发人员对此问题的支持。我与WinForms团队的一名支持工程师通信,我们发现这个问题在某种程度上是由于Accessibility.dll被加载到我的应用程序中,只要微软的平板电脑输入服务(tabtip.exe)正在运行。此服务至少在所有Windows 7 Enterprise安装中都存在,但通常只在您拥有平板电脑或曾在PC上安装任何类型的笔输入设备时才能运行。我以前在PC上使用过Wacom Bamboo笔平板电脑,所以这项服务运行起来很有意义。 请注意,确定我用来填充DataGridView的方法以及我设置的任何属性都与该问题没有任何关系。

Accessibility.dll是微软库,允许某些外围设备(手写板,尤其是辅助设备)更容易互动,并获得约的形式和包含的形式控制的额外信息。我不是100%确定的,但我相信如果安装了这样的外设,这个库会自动加载到每个正在运行的Windows进程中。

检查,我已经提供了转储后,微软的工程师对代码路径的DataGridView决定走下来,发现Accessibility.dll是允许让它发生的罪魁祸首不解。他承认,DataGridView不应该这样做,这似乎是他们最终的问题。但是,即使在他的个人电脑和新制Windows 7虚拟机上打开Tablet PC输入服务后,他也无法重现问题。所以当他能够找出造成我PC上问题的主要角色时,他无法找到根本原因,因此无法进一步追求。

这可能归因于我的特定笔式平板电脑设备(Wacom)或其他所有设备。它的未知。如果有其他人遇到此问题,请与我联系。如果我能缩小事业范围,工程师邀请我联系他。目前,只保留服务可以防止问题发生。

+0

从一天到下一天,我开始定期崩溃免费的LogExpert应用程序,并将其追溯到此问题。我猜是什么触发了在我的机器上启用Tablet PC输入服务(可能插入我的手机?我从未连接过基于笔的设备)。 –

0

我不是完全地理解乌尔问题的探析,但我觉得你的问题是datagridview的记忆缓慢

我有一个解决办法: 1:中断的DataGridView一行到像只页面显示在DataGridView中最大的100行和下一hundread但在吨或其他控制单击它有助于减少乌尔显存 2:上的DataGridView 3启用双Buffred:使用Suspendlayout和恢复布局功能轻易地吸引项目

1

我遇到了DataGridView中的StackOverflowsException非常类似的情况。

条件:

  1. 一个WinForm托管DataGridView控件。 DataGridView属性ReadOnly和VirtualMode设置为true。
  2. VirtualMode的OnCellValueNeeded实现为每MSFT文档(http://msdn.microsoft.com/en-us/library/2b177d6d.aspx
  3. 负载数据的相当大的量(15列×1×10^5行)
  4. 行为datagridview的是正常的(即:GUI的响应,行和如果只显示10列X 30行[300个单元格],则垂直滚动显示垂直&)。当我最大化显示,使得显示的单元格数量大得多时,DataGridView中的StackOverflowsException被触发。
  5. 我也有一个附加的Wacom数位板到我的电脑。
  6. 问题消失,如果我停止Tablet PC输入服务(tabtip.exe)

所以......在我的情况,事实上,弗兰克斯的解决方法是在正确的方向和支持的想法,1。平板电脑输入服务是一个罪魁祸首,2.屏幕中显示(活动)单元的数量对解除异常有影响。

0

我有同样的问题的GridView与50K记录。使用ScrollBar或者只是移动大量的记录导致DataGridView中的StackOverflowsException。阅读完上述内容之后,我简单地停止了虚拟屏幕键盘(我的屏幕是触摸屏)。服务说明“启用触摸键盘和手写面板的笔和墨水功能”

只要停止,GridView就完美地工作。

1

首先,感谢@Frank Weindel用于指向这个奇怪的问题(只有微软能拿出这一点)。

对于那些不想禁用“Tabtip.exe”作为要求的一部分,说你的应用程序是用于平板电脑,只有可能的输入法是Tabtip,有一种解决方法。

您可以在发生崩溃的事件中杀死Tabtip。对我而言,当我选择行数超过60,000的项目时。这就是我所做的。

Private Sub DataGridView1_Scroll(sender As Object, e As ScrollEventArgs) Handles DataGridView1.Scroll 
    Call closeKeyboard() 
End Sub 

'When a user have to type something in textbox' 
Private Sub Lookup_Tbox_MouseDown(sender As Object, e As MouseEventArgs) Handles Lookup_Tbox.MouseDown 
    Call OpenKeyboard() 
End Sub 

Public Sub OpenKeyboard() 
    System.Diagnostics.Process.Start("tabtip.exe") 
End Sub 

Public Sub closeKeyboard() 

    Dim proc() As System.Diagnostics.Process = Process.GetProcessesByName("tabtip") 
    For i As Integer = 0 To proc.Length - 1 
     proc(i).Kill() 
    Next i 
End Sub 

希望它可以帮助别人快乐:) :)战斗

0

我的问题描述,阅读在这里和我自己经过试验确切的问题,这解决了我的问题:

private void dataGridView1_Scroll(object sender, ScrollEventArgs ex) 
{ 
    try 
    { 
     dataGridView1.Focus(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
}