使用DataGridView的StackOverflowException

Fra*_*del 7 c# stack-overflow datagridview

这是一个奇怪的.我有一个DataGridView.我正在设置我自己的自定义类DataSourceList包含对象.列表中大约有50,000个项目.我定义了我希望在Designer中可见的所有列,并设置AutoGenerateColumns为false.

一旦我设置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 
    ...
Run Code Online (Sandbox Code Playgroud)

由于某种原因,该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;
Run Code Online (Sandbox Code Playgroud)

当时间来填充网格视图时,我只需执行以下操作:

dataGridView.DataSource = myList;
Run Code Online (Sandbox Code Playgroud)

Fra*_*del 10

固定

目前还没有人知道修复.

解决方法

从"控制面板"的"服务"面板中禁用Tablet PC输入服务(也称为tabtip.exe).

细节

几个星期前,我联系了Microsoft Developer对这个问题的支持.我用相对应的WinForms的团队支持工程师和我们想通了,这个问题在某些方面造成Accessibility.dll被加载到我的应用程序,每当微软的Tablet PC输入服务(tabtip.exe)正在运行.此服务至少存在于所有Windows 7 Enterprise安装中,但通常仅在您拥有Tablet PC或在PC上安装了任何类型的笔输入设备时才会运行.我过去曾经在我的电脑上使用过Wacom Bamboo数位板,所以为什么这项服务正在运行才有意义.请注意,确定我用于填充的方法DataGridView和我设置的任何属性都与此问题无关.

Accessibility.dll是一个Microsoft库,允许某些外围设备(笔平板电脑,尤其是辅助设备)更容易地进行交互,并获得有关表单和表单中包含的控件的额外信息.我对此并不是100%肯定,但我相信如果安装了这样的外围设备,这个库会自动加载到每个正在运行的Windows进程中.

在检查了我提供的转储后,微软工程师对代码路径感到困惑,DataGridView决定关闭并发现Accessibility.dll是允许它发生的罪魁祸首.他承认DataGridView不应该这样做,这似乎是他们的问题.然而,即使在他的PC和新制造的Windows 7 VM上打开Tablet PC输入服务之后,他也无法重现这个问题.因此,虽然他能够识别导致我的PC出现问题的关键人物,但他无法找到根本原因,因此无法进一步追求.

这可能归因于我特定的笔平板设备(Wacom)或其他所有东西.它未知.如果有其他人遇到此问题,请与我联系.如果我能够缩小原因,工程师邀请我与他联系.目前,仅关闭服务可防止出现此问题.