Дизайн пользовательской вкладки в C # WinForms? - PullRequest
6 голосов
/ 02 марта 2012

У меня есть приложение ac # WinForm, которое мне нужно для генерации TabPages во время выполнения.В идеале я хотел бы спроектировать эти вкладки, используя конструктор VS, но, похоже, я не могу сделать это напрямую, так как не могу перетащить его из панели инструментов (есть ли другой способ?).

У меня есть две общие вкладки, которые я буду использовать несколько раз.Один содержит простую электронную таблицу и пару текстовых полей, а другой - график и несколько текстовых полей.Эти страницы со временем станут более сложными.Я ищу лучший способ сделать это.В настоящее время я просто создаю пользовательские классы для каждой вкладки и устанавливаю их как базовый класс TabPage.Например:

public partial class SpreadsheetTabPage : TabPage{} 

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

Итак, чтобы было ясно, я хочу знать, что, по вашему мнению, является лучшим подходом к разработке этих пользовательских вкладок и почему.Пожалуйста, предоставьте базовый пример кода, если это уместно.Мой метод на самом деле не вызывает особых проблем, но я вижу, что добавление элементов на эти страницы позже будет затруднено, особенно без использования дизайнера.

Заранее спасибо за помощь!

Ответы [ 3 ]

6 голосов
/ 03 марта 2012

Вы можете создать свой собственный конструктор 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.Здесь описаны наиболее распространенные функции: Расширенная поддержка времени разработки

3 голосов
/ 02 марта 2012

Если вы создаете пользовательский элемент управления, который содержит ваш tabcontrol, вы можете увидеть конструктор и создать его, как вам нравится, и вы можете добавить некоторый дополнительный код, и все же можете перетащить его из панели инструментов, чтобы использовать его.1002 * Примечание: вы не можете видеть свой пользовательский элемент управления (ни ваш класс, закодированный вручную), пока вы не восстановите ваш проект

2 голосов
/ 14 октября 2014

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

То, что я сделал, было создано UserControl под названием TabPageLibrary.Соответственно, я перетащил на него TabControl и добавил страницы, основываясь на желаемой настройке.Затем я устанавливаю модификатор TabPage для внутреннего использования.Когда мне нужен был конкретный расширенный TabPage - я просто вызывал класс TabPageLibrary и брал нужный мне TabPage для конкретного приложения.Это дало мне возможность повторно использовать определенную предварительно сконфигурированную TabPage в приложении winform

private void PropertiesButton_Click(object sender, EventArgs e)
{
TabPageLibrary library = new TabPageLibrary();
TabPage propertyPage = library.PropertyPage;
this.tabControl.TabPages.Add(propertyPage);
}

Это определенно решило мою проблему - возможно, она будет работать для вашего приложения.

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