Элемент управления .NET DataGridView использует для меня тонну памяти - PullRequest
4 голосов
/ 02 марта 2010

В настоящее время я использую элемент управления DataGridView в своем приложении, и у меня возникает странная проблема с памятью. Я не использую DataBinding вообще, просто ручное заполнение. Данных, которые я помещаю туда, совсем немного. Обычно мы говорим о 20 строках на 20 столбцов данных.

Рабочий процесс для этого элемента управления заключается в том, что у меня есть ComboBox с разными «наборами данных», которые я загружаю по мере их выбора. Таким образом, наиболее распространенным сценарием использования является циклический просмотр наборов данных в comboBox и просмотр их визуализации в dataGrid. Что я вижу, так это то, что когда люди циклически перебирают наборы данных, использование памяти приложения мгновенно скачет с 100 МБ до 1100 МБ, а затем снижается обратно при включении GC. Но если вы циклически перебираете наборы данных (т.е. быстрее, чем GC запускает в), вам не хватит памяти, и приложение умрет.

После отладки я обнаружил, что ОСНОВНАЯ причина, по которой память скачет как сумасшедшая, заключается в том, что у меня есть несколько столбцов в этой сетке данных, которые имеют тип изображения. Я использую их для отображения значка 16x16, который указывает на статус для этой строки. Эти значки хранятся в ImageList, и я просто устанавливаю их в качестве значения для этой ячейки, когда заполняю строки таблицы данных. Если я вынимаю изображения и заменяю их простым текстом, я не вижу абсолютно никаких всплесков памяти.

Так в чем же дело? Почему изображения, крошечные 16x16, приводят к тому, что управление сходит с ума по моей памяти?

Подробнее:

Моя логика при переключении наборов данных:

  • Очистить все строки сетки: dataGrid.Rows.Clear ();
  • Очистить все столбцы: dataGrid.Columns.Clear ();
  • Добавление столбцов в элемент управления dataGrid: (наиболее тип строки и некоторые DataGridViewImageColumn)
  • Добавить данные у меня строка за строкой, используя dataGrid.Rows.Add (object [] data); (данные включают изображения, которые мне нужно использовать в качестве значков).

Ответы [ 5 ]

1 голос
/ 02 марта 2010

Элемент управления DataGridView предназначен для работы с DataBinding. Если вы вообще не используете DataBinding, я предлагаю вам использовать элемент управления ListView.

ListView оптимизирован для отображения изображений. Кроме того, в памяти легче создать экземпляр, чем DataGridView. Кроме того, элемент управления ListView позволяет изменить вид:

  1. ListView.View = View.Details;
  2. ListView.View = View.LargeIcons;
  3. ListView.View = View.List;
  4. ListView.View = View.SmallIcons;
  5. ListView.View = View.Tile.

Это виды, которые вы можете увидеть в проводнике Windows. Нужно только определить себя как LargeIcons ImageList, или SmallIcons ImageList, или один из них, в зависимости от вида, который вы будете видеть для своего пользователя.

Вы также можете отобразить GridLines, как если бы это был DataGridView, просто чтобы дать тот же аспект.

0 голосов
/ 08 декабря 2017

Представления сетки данных имеют утечку памяти, когда дело доходит до изображений. Перед загрузкой данных установите для источника данных datagridview значение null, затем выполните удаление (с помощью GC.Collect ()) для источника данных.

0 голосов
/ 05 июня 2012

Я столкнулся с этой ошибкой, и она, кажется, вызвана ссылкой на изображение из ImageList. Чтобы обойти это, я создал изображения, отображаемые как контент в проекте. Затем я установил значения изображения в datatable с помощью Bitmap.FromImage ("images / test.png"), и эта странная ошибка памяти исчезла.

0 голосов
/ 10 марта 2010

Кстати, я решил сделать это по-другому. Я прибегнул к использованию Custom Painting для рисования своих значков в ячейке. Это получилось намного лучше. Сетка больше не пожирает память с этим решением.

Использование ListView было возможно, но не очень практично, поскольку он поддерживает только размещение значков в первом столбце. Так что я бы в любом случае должен был сделать заказную покраску.

0 голосов
/ 02 марта 2010

В третьем абзаце вы говорите, что у вас есть значки в ImageList, но в маркированном списке логических шагов вы говорите, что добавляете нужные изображения в виде значков в виде массива объектов. Может ли быть добавлен ImageList, добавленный в dataGrid?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...