2009-05-09 4 views
5

Я использую System.Windows.Forms.DataGrid. Он заполнен примерно 3000 рядами и очень медленно перерисовывается. Если я минимизирую и максимизирую свою форму, все остальные элементы управления просто отображаются, но в конечном итоге я просматриваю перерисовку DataGrid по строкам. Все в этом DataGrid является только для чтения, если это имеет значение.DataGrid slow to Redraw

Update:

Я не совсем уверен, как правильно реализовать событие CellValueNeeded() для моего проекта, или, если это поможет производительность DataGrid в моем случае.

Я создаю элемент управления пользователя, который содержит DataGridView (см. Ниже код). Когда вызывается метод SetProject(), мой элемент управления задается конкретным экземпляром моего класса Project. Затем элемент управления использует статический метод Informa.Data.GetProjectDataTable (Project proj) для извлечения DataTable из проекта. Затем свойство DataSource DataGrid устанавливается на возвращаемый DataTable.

Это первый раз, когда я сделал что-либо с ADO или DataGrids, так что несите меня. Похоже, что CellValueNeed() позволяет мне переопределить, как DataGrid находит значение для одной из его ячеек, но в моем случае это намного сложнее, чем примеры в MSDN. Фактическим источником моих данных является древовидная структура различных объектов Node, корнем которой является экземпляр Project. Каждый узел может иметь переменный набор свойств, который также может быть расширен пользователем во время выполнения. Затем существует множество других сложностей с Nodes, наследующими значения свойств от их родительских узлов, и суммирование других свойств от их дочерних узлов.

Informa.Data.GetProjectDataTable() прорезает все это безумие и генерирует единый плоский DataTable всех свойств всех узлов. На этом этапе мне не нужно связывать изменение таблицы с исходной структурой дерева или обновлять определенные части таблицы при изменении древовидной структуры. Все, что я хочу сделать, это отобразить данные пользователю в DataGrid.

Итак, я реализую CellValueNeeded() для чтения из DataTable, предоставленного Проектом? Я бы подумал, что DataGrid уже знает, как эффективно использовать DataTable в качестве источника данных?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Data; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using Informa; 

namespace Informa 
{ 
public partial class ProjectGridControl : UserControl 
{ 
    private Project proj; 

    public ProjectGridControl() 
    { 
     InitializeComponent(); 
    } 

    public void SetProject(Project proj) 
    { 
     this.proj = proj; 
     UpdateGridControl(); 
    } 

    public void UpdateGridControl() 
    { 
     if (this.proj == null) 
     { 
      this.dataGrid.DataSource = null; 
     } 
     else 
     { 
      //Extracts a DataTable from the project and sets it as the 
      //DataSource of the property grid 
      this.dataGrid.DataSource = Informa.Data.GetProjectDataTable(proj); 
     } 
    } 
} 

}

+0

предлагаю вам разместить некоторые (вырезанные) коды ... –

+0

Какие события увольняют? Какие события вы занимаетесь? Если у вас есть код, запущенный для каждого столбца/строки/ячейки, которая привязана, я бы проверил там. –

+0

Я не занимаюсь никакими событиями. Я создаю DataTable и устанавливаю его как DataSource DataGrid. Вот и все. –

ответ

10

Когда-то был маленький Вольф по имени МакроСофт, который провел некоторое время с Видией Овцы. Они произвели самый медленный рендеринг текста и сетки на планете и запустили всю работу над процессором в год стрельбы аппаратного обеспечения; все, в то время как овцы были уверены, что замедлят его еще дальше.

Если я прав, вы обязаны письмо много :-)

Вы работаете NVidia карту и их дерьмовые драйвера или аналогичные, а также видя MSFT отказывается исправить GDI + для аппаратного ускорения вместе с (даже Mono будет делать это, прежде чем они решат дать вам некоторое энергосбережение и правильное повторное использование оборудования, вы знаете достойную технику).

Оберните свой DataGridView в новый тип (т.е.inherit) и установите для свойства DoubleBuffered значение true, измените код дизайнера на использование этого нового типа.

Визуальный рендеринг «По строкам» - это то, насколько плохо эта отрасль 2009/2010 с суперкомпьютерами на рабочем столе и одной DLL, большая компания отказывается исправлять, но с радостью будет взимать плату за то, что она будет работать еще медленнее на Mounta-Dismounta- Vista. Jokers ..

+2

Да, установка двойного буферизации на истину, похоже, зафиксировала его. Благодарю. –

+3

класс DBDataGridView: System.Windows.Forms.DataGridView { public DBDataGridView() {DoubleBuffered = true; } } – Zsolti

+0

Я заполняю Datagridview, используя bindingsource. У меня около 1000 записей. Я использовал свойство DoubleBuffered и установил его true. Я все еще становлюсь очень медленным. –

2

DataGridView должен hanlde 3000 строк без проблем в виртуальном режиме.

Обязательно установите значение VirtualMode в true (вы упомянули, что попробовали это), а также реализовать CellValueNeeded правильно.

Подробнее читайте в MSDN Walkthrough on VirtualMode.

5

У вас есть автоматическая калибровка для включения столбцов? У меня были пользователи, которые испытывали значительное замедление в нашем приложении всего за 10 строк, потому что была включена автоматическая калибровка. В принципе, одна сетка позволила пользователю проверить/снять флажок, чтобы добавить строку в другую сетку, а вторая сетка будет испытывать экспоненциальное замедление с каждой добавленной строкой.

После некоторого профилирования я обнаружил, что для добавления 5 строк во вторую таблицу потребовалось ~ 12 секунд. Наконец, попробовал отключить автоматическую калибровку столбцов, и теперь это мгновенно.

+0

Автоматическое определение размеров строк и столбцов отключено. Спасибо за предложение. –

+0

@ Крис Доггетт: СПАСИБО, СПАСИБО, СПАСИБО !!! После 1,5 часов отладки, наконец, нашли свой пост. И теперь выбор строки работает примерно на 500% быстрее ;-) – andzep

+0

привет. могу ли я знать, как отключить 'AutoSize'? не можете найти на нем какую-либо документацию. Благодарю. –

4

У меня были большие проблемы с медленным рисунком datagridview. Мне нужно, чтобы я был как можно больше на экране, и казалось, что физический размер его значительно повлиял на скорость боли, чем объем данных и т. Д. Что действительно сделал трюк для меня, это установить CellBorderStyle = None (видимо, каждая ячейка отвечает за рисование собственной границы, что кажется смешным, поскольку границы ячеек остаются фиксированными на экране, поэтому для каждой ячейки не нужно постоянно перерисовывать свои собственные границы при прокрутке, но в любом случае ...).

Теперь сетка без границ ячеек не очень хорошая сетка. Но, к счастью, вы можете установить DividerWidth для столбцов и строк. Эти значения по умолчанию равны 0, но при установке их на 1 (или выше, если вы хотите более толстый) вы вернете свои «ячейки» границы, идентичные по внешнему виду, к CellBorderStyle = Single, но на этот раз нарисовали «статически» (из-за отсутствия лучшего слова) для всего документа datagridview.

Кроме того, задайте свойства AutoResize для False, если у вас много строк.

Улучшение скорости краски было ОГРОМНЫМ, по крайней мере, в моем случае.

+0

Отличное наблюдение! У меня есть виртуальный режим, и ничего не помогло (у меня есть сетка 20x7, 3 обновления за 20 мс через таймер). Но это значительно улучшило производительность. – Alex

+0

Вам нужно это решение, если вы попробовали решение DoubleBuffered? –

0

В Visual Studio 2015, имеющий 2 DataGridView Autosize столбцов значение Нет еще, имеющим

dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders; 

был причиной проблемы очень медленной строки и столбец добавляет пользователя изменения размеров.

Так что, если I REM из вышеприведенной линии, UX работает быстро. См. AutoSizeRowsMode и предположительно та же проблема с AutoSizeColumnsMode