这是一个奇怪的。我有DataGridView
。我正在设置DataSource
,其中List
包含我自己的自定义类的对象。列表中大约有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
...
出于某种原因,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 :(得分:9)
目前尚无人知道。
从“控制面板”的“服务”面板中禁用 Tablet PC输入服务 (a.k.a. tabtip.exe)。
几周前,我就此问题与Microsoft Developer支持人员联系。我与WinForms团队的支持工程师通信,我们发现这个问题在某种程度上是由于 Accessibility.dll 在Microsoft的 Tablet PC输入服务(tabtip。 exe)正在运行。此服务至少存在于所有Windows 7 Enterprise安装中,但通常仅在您拥有Tablet PC或在PC上安装了任何类型的笔输入设备时才会运行。我以前在我的电脑上使用过Wacom Bamboo数位板,所以这个服务运行起来很有意义。 请注意,确定我用于填充DataGridView
的方法或我设置的任何属性都与此问题无关。
Accessibility.dll 是一个Microsoft库,允许某些外围设备(笔平板电脑,尤其是辅助设备)更轻松地进行交互,并获取有关表单和表单中包含的控件的额外信息。我对此并不是100%肯定,但我相信如果安装了这样的外围设备,这个库会自动加载到每个正在运行的Windows进程中。
在检查了我提供的转储后,Microsoft工程师对DataGridView
决定关闭的代码路径感到困惑,发现 Accessibility.dll 是允许的罪魁祸首让它发生。他承认DataGridView
不应该这样做,这似乎是他们的问题。然而,即使在他的PC和新制造的Windows 7 VM上打开Tablet PC输入服务之后,他也无法重现这个问题。因此,虽然他能够识别导致我的PC出现问题的主要参与者,但他无法找到根本原因,因此无法进一步追求。
这可能归因于我特定的笔式平板设备(Wacom)或其他所有东西。它未知。如果有其他人遇到此问题,请与我联系。如果我能够缩小原因,工程师邀请我与他联系。现在,只需保持关闭服务就可以解决问题。
答案 1 :(得分:1)
我在DataGridView中遇到过类似StackOverflowsException的情况。
条件:
所以...在我的情况下,确实,Franks的解决方法是正确的方向,并支持这样的想法:1。Tablet PC输入服务是罪魁祸首2.屏幕中显示的(活动)单元格的数量有触发异常的效果。
答案 2 :(得分:1)
首先,感谢@Frank Weindel指出这个WEIRD问题(只有微软才能提出这个问题)。
对于那些不想禁用“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
希望它可以帮助某人:)快乐的战斗:)
答案 3 :(得分:0)
我不完全理解你的问题,但我认为你的问题很慢 datagridview和memory
我有一个解决方案: 1:将datagridview行分解为只显示Datagridview中最多100行的页面以及按钮或其他控件中的下一个hundread单击它有助于减少视频内存 2:在DataGridView上启用Double Buffred 3:使用Suspendlayout和恢复布局功能轻松绘制项目
答案 4 :(得分:0)
我有同样的问题GridView有50K记录。使用ScrollBar或只是移动大量记录导致DataGridView中的StackOverflowsException。阅读完上述内容后,我简单地停止了虚拟屏幕键盘(我的屏幕是触摸屏)服务描述“启用触摸键盘和手写面板笔和墨水功能”
一旦停止,GridView就能完美运行。
答案 5 :(得分:0)
我有问题所描述的确切问题,在阅读完这里和我自己的实验后,这解决了我的问题:
private void dataGridView1_Scroll(object sender, ScrollEventArgs ex)
{
try
{
dataGridView1.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}