Нужна помощь в создании элемента управления для отображения данных
Я пишу.NET WinForms-приложение, которое должно отображать список результатов в удобном для пользователя формате. Вот как я надеюсь отобразить данные.
http://img398.imageshack.us/img398/4336/imgdyu.png
Таблица должна поддерживать приличный объем данных (>= 200 отдельных "блоков данных") и должна быть достаточно быстрой. Я не уверен в самом легком способе сделать это, и я надеялся на некоторое руководство и совет. Я создал быстрый прототип пользовательского элемента управления, который просто использовал набор текстовых полей, расположенных друг над другом. Это работало довольно хорошо, но в Windows слишком быстро заканчиваются дескрипторы для текстовых полей. Я мог бы создать собственный текстовый элемент управления, но это заняло бы много времени, и мне было интересно, есть ли какие-либо рекомендации для альтернативных решений? Благодарю.
8 ответов
Вы можете использовать сторонний элемент управления для этого (возможно), но вот несколько причин, почему это потенциально плохая идея:
- сторонние контроли стоят денег
- сторонние элементы управления имеют тенденцию сосать
- сторонние элементы управления требуют, чтобы вы распространяли хотя бы дополнительную DLL, над которой вы обычно не имеете никакого контроля
- даже если сторонний контроль в конечном итоге может сделать то, что вам нужно, вам потребуется время и усилия, чтобы понять, как его использовать и как придать ему форму, которая вам нужна
Для чего-то необычного (например, то, что вы делаете) лучше всего написать собственный UserControl по следующим (среди прочих) причинам:
- написание собственного UserControl - самое интересное, что вы можете сделать в.Net
- вам нужно научиться некоторым вещам, чтобы сделать это хорошо, но полученные знания сразу же можно перенести на другие проблемы и проекты (тогда как все, что вы узнаете об использовании бесконечного Wonderfulness Gridifier от Initrode, только поможет вам в использовании этого конкретного элемента управления)
- не будет ничего дополнительного для распространения с вашим приложением
- полный контроль над исходным кодом
- бесплатно навсегда (с извинениями Эвони)
- небо - это предел - с любым сторонним контролем вы в конечном итоге столкнетесь с чем-то, чего оно просто не может сделать, но если вы делаете это самостоятельно, вы можете буквально делать все, что захотите
Ваша конкретная проблема (хорошо описанная в вашем вопросе, благодаря графике) довольно проста как пользовательский элемент управления, в основном нарисованный владельцем (с TextBox или двумя добавленными в микс). Единственные методы, которые вам понадобятся от объекта System.Drawing.Graphics, - это DrawRectangle, FillRectangle, MeasureString и DrawString. Вам даже не понадобится любая документация, так как Intellisense предоставит вам все необходимое.
Если у вас возникнут проблемы, я напишу для вас шоколадное печенье.:)
Обновление: поскольку вам нужен текст, который можно выбрать, это немного усложняет этот подход. Реализация вашей собственной функциональности типа Textbox- гигантская боль в петарде, но относительно простым решением является добавление реального многострочного Textbox поверх любого текстового прямоугольника, когда пользователь нажимает на него, и помещать текст прямоугольника (предварительно выбранный) в текстовое поле. Когда это временное текстовое поле теряет фокус (LostFocus), вы отрисовываете отредактированный текст в прямоугольник и удаляете текстовое поле. Таким образом, у вас есть только одно Textbox за раз в вашем UserControl.
Эта версия будет стоить вам два куки.
Обновление 2: Вот простое приложение, которое демонстрирует, как использовать один TextBox для выбора и редактирования всего элемента управления. А вот и исходный код.
Не зная больше о типе данных, я думаю, что вам нужен пользовательский элемент управления, который будет "повторяться". Вы можете использовать контейнерный элемент управления TableLayout (или, возможно, FlowLayout?) И добавлять / удалять элементы из таблицы по мере необходимости.
Если ваши данные являются табличными, возможно, с отношениями родитель / потомок, я бы сказал, что вы должны использовать элемент сетки. Я не согласен с утверждением другого ответа, что вам следует избегать стороннего контроля. Они очень быстро сэкономят ваше время - некоторые, например, контроль Janus GridEx, стоят относительно дешево (несколько сотен фунтов) и сэкономят ваши часы - что, если вы работаете в коммерческой среде, может привести к гораздо большему, чем стоимость контроль. Кроме того, они выглядят намного лучше и предлагают лучшую функциональность, чем стандартный элемент управления WinForms Grid.
Я не знаю природу данных, которые вы хотите отобразить, но для быстрого выполнения System.Windows.Forms.DataGridView хорошо справляется со своей задачей и встроен в.Net Framework 2.0.
Если вы привыкли работать с классами Linq to SQL, если вы используете SQL Server в качестве хранилища данных, просто создайте диаграмму DBML и:
- Добавить источник данных;
- В окне инструмента "Источник данных" выберите отображение в виде сетки и перетащите его на форму;
- Отредактируйте столбцы и измените их порядок так, как вы хотите, чтобы они отображались для вашего клиента;
- В коде установите DataGridView.DataSource = someObject.GetList(), который будет возвращать IList объекта, который вы хотите отобразить в этой сетке.
Для этого требуется всего около десяти строк кода и несколько времени разработки Windows Forms. Надеюсь, я не забыл ничего принципиального.:-П
Пожалуйста, дайте знать, помогает ли это!
Будет ли DataRepeater
из Visual Basic PowerPack у вас работает? Это загрузка для VS2k5 и устанавливается вместе с VS2k8. Если нет, проверьте TemplateListBox
на www.codeproject.com/KB/cpp/TemplateListBox.aspx и ContinousControl
на blogs.vbcity.com/hotdog/archive/2006/10/26.aspx.
Мне кажется, это отличное упражнение в элементах управления, которые окрашены самостоятельно. Вместо создания текстовых полей переопределите / подпишитесь на событие OnPaint и используйте объект Graphics для DrawString() в соответствующих местах, DrawRectange(), чтобы вокруг них были прямоугольники. Если вы знаете положение ваших текстовых полей, существующий код будет довольно легко конвертировать.
Несколько советов:
- для первой версии: не беспокойтесь об ограничении вашего рисунка видимой частью элемента управления (я думаю, вам понадобится прокрутка здесь)
- for (1) - графика сделает за вас вырезку, и вы сможете позаботиться об этом вручную, когда подтвердите, что у вас есть верный макет и правильные данные на экране
- использовать двойную буферизацию, чтобы уменьшить мерцание всеми средствами
- использовать солнцезащитный крем
Не стесняйтесь комментировать с дальнейшими вопросами...
Возможно, вы захотите опубликовать свойство EditingControl для вашего объекта, если вы написали его самостоятельно, и создать новый экземпляр для каждого экземпляра вашего класса, извлеченного из базы данных.
someObject.GetList().ForEach((so) => {
ConstructorInfo ctor = so.EditingControl.GetType().GetConstructor(new Type[] { });
var editingControl = ctor.Invoke(new object[] { });
editingControl.Name = "someName" + ++counter.ToString();
editingControl.Location = new Point(posX, posY);
editingControl.Width = someWidth;
editingControl.Height = someHeight;
editingControl.DataSource = so;
myForm.Controls.Add(editingControl);
});
Ну, я надеюсь, вы поняли идею. Это не очень оптимальное решение, но в любом случае, на мой взгляд, довольно хорошее.
Надеюсь это поможет!
Для этого можно использовать элемент управления WinForm Grid или любые сторонние элементы Grid или List.
WPF ListBox с шаблоном данных также может достичь аналогичного поведения.
Если это веб-приложение:
Редактируются ли эти данные на странице, или это только для целей отображения? Если первое, рассмотрите возможность сделать каждый элемент ссылкой на новую страницу редактора, которая будет редактировать один блок за раз.
Если вы только отображаете данные без возможности редактирования, используйте элемент управления повторителем для вывода таблицы HTML. Взгляни на
http://quickstarts.asp.net/QuickStartv20/aspnet/doc/ctrlref/data/repeater.aspx
Повторитель привязывается к любому источнику данных - List<>, Array, DataTable и т. Д. - и перебирает содержимое, и отображает данные для каждой строки в соответствии с шаблоном, который вы указали в aspx.
Если это приложение WinForms
Спросите себя, почему ваше приложение не является веб-ориентированным. В настоящее время (по моему скромному мнению) очень мало приложений, которые лучше подходят для реализации winForms. Графические редакторы, компиляторы и т. Д. Являются хорошими примерами. Однако механизм отчетности, скорее всего, лучше подходит для веб-реализации. YMMV.
Если вы по-прежнему используете WinForms, лучшим решением может быть использование метки или другого элемента управления без ручек для вашего текста. Ссылка на другую форму, если вам нужно редактировать каждую запись. Любая страница с тысячами текстовых полей обеспечит ограниченное удобство использования.