StackOverflowException с DataGridView
это странно. У меня есть DataGridView
. Я устанавливаю его DataSource
С List
содержащих объекты моего собственного пользовательского класса. В списке около 50 000 пунктов. Я определил все столбцы, которые я хотел видеть в конструкторе, и установил 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
?
EDIT:
меня попросили какой-то код. Это сгенерированный дизайнером код для 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;
6 ответов
исправить
в настоящее время не известно никаких исправлений.
решение
отключить служба ввода планшетных ПК (a.к. a. tabtip.exe) из панели в Панель управления.
подробности
несколько недель назад я связался с поддержкой разработчиков Microsoft по этой проблеме. Я переписывался с инженером поддержки в команде WinForms, и мы выяснили, что эта проблема была каким-то образом вызвана доступность.dll файлы загружается в мое приложение всякий раз, когда Microsoft Tablet PC Input Service (tabtip.exe). Эта служба присутствует по крайней мере на всех установках Windows 7 Enterprise, но, как правило, работает только если у вас есть планшетный ПК или когда-либо устанавливали какой-либо пера устройства ввода на вашем компьютере. В прошлом я использовал планшет Wacom Bamboo pen на своем ПК, поэтому было понятно, почему эта служба работает. обратите внимание, что было определено, что ни метод, который я использовал для заполнения DataGridView
ни одно из свойств, которые я установил, не имело ничего общего с проблемой.
доступность.dll файлы - это библиотека Microsoft, которая позволяет некоторым периферийным устройствам (планшетам и особенно вспомогательным устройствам) легче взаимодействовать и получать дополнительную информацию о формах и элементах управления, содержащихся в формах. Я не уверен на 100% в этом, но я считаю, что эта библиотека загружается в каждый запущенный процесс Windows автоматически если такое периферийное устройство установлено.
после изучения дампа, который я предоставил, инженер Microsoft был озадачен путем кода, который DataGridView
решил спуститься и обнаружил, что доступность.dll файлы был виновником, который позволил этому случиться. Он признал это DataGridView
не должен делать этого, и это казалось проблемой с их стороны. Однако он не смог воспроизвести проблему на своем конце даже после включения службы ввода планшетного ПК на обоих его ПК и свежеприготовленная Windows 7 VM. Поэтому, хотя он смог определить ключевых игроков, которые вызвали проблему на моем компьютере, он не смог найти первопричину и, следовательно, не смог продолжить ее.
Это может быть связано с моим конкретным планшетным устройством (Wacom) или чем-то еще вместе. Это неизвестно. Если кто-то еще сталкивается с этой проблемой, пожалуйста, свяжитесь со мной. Инженер предложил мне связаться с ним, если я смогу сузить круг подозреваемых. Сейчас просто поддерживаю service off предотвращает проблему.
Я столкнулся с очень похожим сценарием StackOverflowsException в DataGridView.
условия:
- WinForm с элементом управления datagridview. Свойств datagridview readonly и VirtualMode значение true.
- VirtualMode OnCellValueNeeded реализован в соответствии с документацией MSFT (http://msdn.microsoft.com/en-us/library/2b177d6d.aspx)
- загрузите значительный объем данных (15 столбцов x 1 x 10^5 rows)
- поведение datagridview нормально (т. е.: отзывчивость GUI, выбор строки и ячейки, вертикальная и горизонтальная прокрутка), если отображается только 10 столбцов X 30 строк [300 ячеек]. Когда я максимизирую отображение так, чтобы количество отображаемых ячеек было намного больше, stackoverflowsexception в DataGridView запускается.
- у меня тоже есть прикрепленный планшет Wacom к моему компьютеру.
- проблема исчезнет, если я остановлю службу ввода планшетного ПК (tabtip.exe)
Итак...в моем случае, действительно, обходной путь франков находится в правильном направлении и поддерживает идею, что 1. служба ввода планшетных ПК является виновником и 2. количество отображаемых (активных) ячеек на экране влияет на запуск исключения.
прежде всего, спасибо @Frank Weindel за указание на эту странную проблему (только microsoft может придумать это).
для тех, кто не хочет отключать "Tabtip.exe " в рамках требования, скажем, ваше приложение для планшета и только возможный метод ввода 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
надеюсь, это поможет кому-то:) Happy fighting:)
Я не полностью понимаю UR promblem, но я думаю, что проблема ur-это медлительность datagridview и памяти
У меня есть решение : 1: разбейте строку datagridview на страницы, такие как только показать максимум 100 строк в Datagridview и далее сотню в кнопке или другом элементе управления нажмите на нее, чтобы уменьшить объем видеопамяти ur 2. включение двойной Buffred на элементе управления datagridview 3: Используйте Suspendlayout и возобновите функцию макета, чтобы легко нарисовать элемент
У меня была такая же проблема GridView с записями 50K. Использование полосы прокрутки или просто перемещение большого количества записей вызвало исключение StackOverflowsException в DataGridView. После прочтения выше я просто остановил виртуальную экранную клавиатуру (мой экран-сенсорный экран) описание службы "включает сенсорную клавиатуру и функциональность панели рукописного ввода и чернил"
Как только это было остановлено, GridView работал отлично.
У меня была точная проблема, как описано в вопросе, после прочтения здесь и моих собственных экспериментов, это решило мою проблему:
private void dataGridView1_Scroll(object sender, ScrollEventArgs ex)
{
try
{
dataGridView1.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}