Дизайн пользовательской вкладки в C# WinForms?
У меня есть приложение c# WinForm, которое мне нужно создать вкладки во время выполнения. В идеале я хотел бы создать эти вкладки с помощью VS designer, но кажется, что я не могу напрямую сделать это, поскольку я не могу перетащить его из панели инструментов (есть ли другой способ?).
У меня есть две общие вкладки, которые я буду использовать несколько раз. Один из них содержит простую электронную таблицу и пару текстовых полей, а другой-график и пару текстовых полей. Эти страницы в конечном итоге получат посложнее. Я ищу лучший способ сделать это. В настоящее время я просто создаю пользовательские классы для каждой вкладки и устанавливаю его как базовый класс TabPage. Например:
public partial class SpreadsheetTabPage : TabPage{}
Я читал, что пользовательские элементы управления предлагают некоторую форму альтернативы, но я действительно не понимаю преимуществ использования его против моего метода.
чтобы быть ясным, я хочу знать, что вы считаете лучшим подходом к разработке этих пользовательских страниц и почему. Пожалуйста, предоставьте базовый пример кода, если это необходимо. Мой метод на самом деле не вызывает слишком много проблем, но я вижу, что добавление вещей на эти страницы позже будет сложно, особенно без использования дизайнера.
Спасибо за вашу помощь заранее!
3 ответов
Если вы создадите пользовательский элемент управления, содержащий ваш tabcontrol, вы можете увидеть дизайнера и спроектировать его, как вам нравится, и вы можете добавить дополнительный код, и все еще можете перетащить его из toolbox, чтобы использовать его.
Примечание: вы не можете видеть, как вы управляете пользователем (ни ваш кодированный вручную класс), пока вы восстановить проект
вы можете создать свой собственный конструктор TabControl и реализовать необходимые функции во время разработки. Вот код самой простой версии такого конструктора:
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;
using CustomTabControlExample.TabControl;
namespace CustomTabControlExample.Design {
public class CustomTabControlDesigner :ParentControlDesigner {
DesignerVerbCollection fVerbs;
public override DesignerVerbCollection Verbs {
get {
if (fVerbs == null)
fVerbs = new DesignerVerbCollection(new DesignerVerb[] {
new DesignerVerb("Add Tab", OnAdd)
});
return fVerbs;
}
}
void OnAdd(object sender, EventArgs e) {
TabPage newPage = (TabPage)((IDesignerHost)GetService(typeof(IDesignerHost))).CreateComponent(
typeof(CustomTabPage));
newPage.Text = newPage.Name;
((System.Windows.Forms.TabControl)Component).TabPages.Add(newPage);
}
public override void InitializeNewComponent(IDictionary defaultValues) {
base.InitializeNewComponent(defaultValues);
for (int i = 0; i < 2; i++)
OnAdd(this, EventArgs.Empty);
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
// Selection of tabs via mouse
if (m.Msg == 0x201/*WM_LBUTTONDOWN*/) {
System.Windows.Forms.TabControl control = (System.Windows.Forms.TabControl)Component;
int lParam = m.LParam.ToInt32();
Point hitPoint = new Point(lParam & 0xffff, lParam >> 0x10);
if (Control.FromHandle(m.HWnd) == null) // Navigation
if (hitPoint.X < 18 && control.SelectedIndex > 0) // Left
control.SelectedIndex--;
else control.SelectedIndex++; // Right
else // Header click
for (int i = 0; i < control.TabCount; i++)
if (control.GetTabRect(i).Contains(hitPoint)) {
control.SelectedIndex = i;
return;
}
}
}
protected override void OnDragDrop(DragEventArgs de) {
((IDropTarget)((System.Windows.Forms.TabControl)Component).SelectedTab).OnDragDrop(de);
}
protected override void OnDragEnter(DragEventArgs de) {
((IDropTarget)((System.Windows.Forms.TabControl)Component).SelectedTab).OnDragEnter(de);
}
protected override void OnDragLeave(EventArgs e) {
((IDropTarget)((System.Windows.Forms.TabControl)Component).SelectedTab).OnDragLeave(e);
}
protected override void OnDragOver(DragEventArgs de) {
((IDropTarget)((System.Windows.Forms.TabControl)Component).SelectedTab).OnDragOver(de);
}
}
}
Это кажется довольно сложным способом, но как только вы его узнаете, вы будете впечатлены мощными возможностями, предоставляемыми Visual Studio. Вы можете найти много информации в MSDN. Здесь описаны наиболее распространенные особенности:Расширение Поддержки Времени Разработки
я наткнулся на эту ветку с тем же вопросом в голове. Поразмыслив над проблемой, я понял, что решение стоит передо мной. Это на самом деле довольно простой и элегантный.
то, что я сделал, было создано UserControl под названием TabPageLibrary. Соответственно, я перетащил на него TabControl и добавил страницы на основе настройки, которую я хотел. Затем я установил модификатор TabPage в internal. Когда мне нужна конкретная расширенная страница табуляции - я просто вызову класс TabPageLibrary и возьмите TabPage мне нужно для конкретного приложения. Это дало мне возможность повторно использовать определенную предварительно настроенную страницу табуляции во всем приложении winform
private void PropertiesButton_Click(object sender, EventArgs e)
{
TabPageLibrary library = new TabPageLibrary();
TabPage propertyPage = library.PropertyPage;
this.tabControl.TabPages.Add(propertyPage);
}
это, безусловно, решило мою проблему - возможно, это сработает для вашего приложения.