Супер медленный пользовательский элемент управления C # - PullRequest
2 голосов
/ 26 февраля 2009

Я создал пользовательский элемент управления, это FlowLayoutPanel, в который я поместил множество других пользовательских элементов управления (только кнопки, каждый с тремя надписями и наложенным PictureBox)

Работает нормально примерно с 100 кнопками, но увеличьте их до 1000, и проблема в этом. Увеличьте его до 5000, и он просто умрет через 20 секунд.

У меня очень мало пользовательского кода, и я разумно использую макет приостановки и возобновления.

Так что я делаю не так? Я уверен, что мой (довольно быстрый) компьютер должен обрабатывать несколько тысяч кнопок и меток.

(Я довольно новичок в C # GUI, так что, возможно, мне все равно придется делать все по-другому.)

Редактировать 1:

На данный момент это практически единственный пользовательский код:

flowLayoutPanel1.SuspendLayout();
foreach (DataRow row in dt.Rows) // dt is from a DB query
{
    flowLayoutPanel1.Controls.Add(new PersonButton(row));
}
flowLayoutPanel1.ResumeLayout();

и в конструкторе PersonButton:

this.label1.Text = row["FirstName"].ToString().Trim() + " "
    + row["Surname"].ToString().Trim();

(К нему должна быть приложена картинка, но я не уверен, что кто-нибудь ее увидит.)

Редактировать 2:

Полагаю, мне действительно следует использовать DataGridView или ListView, но я хотел больше, чем просто строка текста и маленький значок в строке; Я хотел, чтобы он выглядел аналогично представлению загрузок в Firefox (Ctrl + J). (См. Скриншот)

Большое спасибо за ваш вклад, кстати. Я думаю, мне придется переосмыслить ...

альтернативный текст http://img156.imageshack.us/img156/1057/capture.png

Ответы [ 7 ]

14 голосов
/ 26 февраля 2009

Может ли приложение C # WinForm обрабатывать 1000 экземпляров любого типа элемента управления? Я не гуру WinForm, но то, что вы ожидаете от своего приложения, может быть необоснованным.

Тот факт, что вы хотите показать 1000+ элементов управления любого типа, может быть признаком того, что вы подходите к дизайну своего программного обеспечения с неправильной стороны.

2 голосов
/ 26 февраля 2009

Вы должны будете опубликовать часть кода макета, иначе мы не сможем сильно / вообще помочь.

Кроме того, ваш лучший выбор № 1 - профилировать ваш код. Профилирование - единственный верный способ узнать, что именно медленно работает в вашем коде. По моему опыту, это особенно верно для кода пользовательского интерфейса.

1 голос
/ 25 июля 2013

[Necromantic mode = ON]

У вас есть 1000 строк данных, но вы можете показать только некоторые из них, поэтому создайте только те элементы управления, которые будут видны, и используйте их повторно, меняя их содержимое с новыми данными при прокрутке.

1 голос
/ 26 февраля 2009

Логика компоновки, необходимая для элементов управления 5k, будет слишком большой для любого типа оберточной панели. Возможно, вы захотите взглянуть на другой тип элемента управления, предназначенный для хранения тысяч записей - что-то вроде DataGridView .

DataGridView имеет несколько различных типов столбцов , доступных для работы с типом отображаемых данных (изображения, кнопки, метки). Поскольку ваш запрос к базе данных, похоже, возвращает DataTable, вы можете просто связать это непосредственно с вашим DataGridView и удалить цикл.

1 голос
/ 26 февраля 2009

Похоже, вам серьезно нужно переосмыслить интерфейс.

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

Однако я провел некоторые эксперименты, рассматривая время для создания новых элементов управления в коде, даже с использованием отражения, и обнаружил, что несколько сотен связанных с данными элементов управления, созданных на лету в панели макета потока, должны быть созданы за 1-2 секунды .

Размещение большего количества примеров кода может помочь получить лучший ответ.

Дополнительная информация: Я только что снова запустил свой тест синхронизации, 300 элементов управления заняли 0,5 секунды, 400 - 1,9 секунды, 600 - 3 секунды, 1000 - 6 секунд.
Кажется, что где-то между 300 и 400 существует предел, когда ресурсы начинают перерасходоваться.

1 голос
/ 26 февраля 2009

При 1000+ кнопках у вас, вероятно, слишком мало ресурсов GDI и / или необработанных дескрипторов для вашего приложения.

Не уверен, что ваше приложение должно делать, но сетка или поле со списком может быть лучшим вариантом здесь.

0 голосов
/ 28 июля 2015

Попробуйте это; оставьте этот метод в вашем коде.

защищенное переопределение CreateParams CreateParams { получить { CreateParams cp = base.CreateParams; cp.ExStyle | = 0x02000000; вернуть cp; } }

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