Проблема при добавлении большого количества элементов управления в .NET Windows Form (C #) - PullRequest
1 голос
/ 26 сентября 2008

У меня есть приложение Windows Form, написанное на C #. Его работа заключается в отправке сообщений в список пользователей. Пока эти сообщения отправляются, я бы хотел отобразить состояние операции для каждого пользователя. Что я делаю (для каждого пользователя) - это создание элемента управления Label и добавление его в Panel. Это работает без проблем для небольшого набора пользователей. Когда я увеличиваю размер до 1000 или более, отладчик Visual Studio отображает следующее сообщение:

Первое случайное исключение типа 'System.ComponentModel.Win32Exception' произошло в System.Windows.Forms.dll Первое исключение типа «System.Reflection.TargetInvocationException» произошло в mscorlib.dll

А потом приложение зависает. Есть мысли о том, что я делаю неправильно и как я могу это исправить?

Ответы [ 8 ]

3 голосов
/ 26 сентября 2008

Учитывая размер, я бы рассмотрел отображение вашего статуса в RichTextBox.

Происходит то, что вы генерируете слишком много дескрипторов, и Framework не может обработать их все.

3 голосов
/ 26 сентября 2008

Вместо этого используйте DataGridView

2 голосов
/ 26 сентября 2008

Это обходной путь, но я не думаю, что ваши пользователи действительно хотят просматривать список из 1000 человек. Покажите им текущий / самый последний и сводный отчет для остальных. Или пусть они пролистают его.

1 голос
/ 26 сентября 2008

Мне нравится использовать ListView в режиме подробностей. Обычно я создаю подпрограмму для добавления строки, выбора ее и вызова элемента EnsureVisible() для автоматического перехода к нему.

Как уже упоминалось, элементы управления соотносятся с одним или несколькими дескрипторами окна, а ОС может выдавать только столько.

1 голос
/ 26 сентября 2008

Вместо этого поместите ProgressBar в форму. Если вы отправляете одно сообщение для 1000 человек, просто увеличивайте ProgressBar на 1 каждый раз, когда отправляете сообщение.

Если вы отправляете 5 сообщений для 1000 человек, используйте один индикатор выполнения для сообщений и один для людей (второй индикатор будет циклически перебирать значения по одному для каждого значения в первом столбце).

Вы также можете иметь метку для каждого индикатора выполнения (например, «95% завершено» или «Сообщение 3 из 5» или что-то в этом роде).

Вы не можете иметь такое большое количество элементов управления в форме .NET, и даже если бы вы могли, ни один пользователь не мог смотреть на них все одновременно.

1 голос
/ 26 сентября 2008

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

Я бы использовал Grid или Listview для отображения пользователя и статуса отправляемого им сообщения. Эти элементы управления могут обрабатывать неограниченное (строго ограниченное системной памятью) количество строк. Одна строка на пользователя (или одна строка на сообщение - что работает лучше).

Это должно быть единственное, что происходит в потоке пользовательского интерфейса. Используйте фонового работника (класс BacngroundWorker) или структуру очереди сообщений (MSMQ, сервер SQL), чтобы сообщения отправлялись асинхронно и создавались отчеты о состоянии обратно через BackgroundWorker.

Что касается вашей конкретной ошибки - я не знаю, почему вы ее получаете. Не должно быть никаких ограничений на количество меток, которые вы можете поместить в WinForm. Я подозреваю, что ошибка вызвана чем-то другим.

0 голосов
/ 26 сентября 2008

Если вы буквально показывает только метки на панели, я бы посоветовал вам показывать статусы с использованием GDI. Напишите текст видимой области в OnPaint и сделайте недействительной область метки состояния только при ее изменении.

0 голосов
/ 26 сентября 2008

Слишком много элементов управления! Сделайте единый элемент управления, чтобы содержать все эти сообщения о состоянии. Как насчет многострочного текстового поля?

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