В один момент возникла задача сделать TabControl по отрисованному дизайну, с вкладками с левой стороны. Попытался реализовать эту задачу средствами класического TabControl, но встретился со множеством проблем, связанных с этим.
Первой проблемой стало то, что если спозиционировать вкладки с левой стороны, то мы получаем следующую картину:
Но мне нужно было, чтобы надписи шли гаризонтально. Изучив чуть глубже данный контрол, решил воспользоваться параметром DrawMode=OwnerDrawFixed. Все надписи стерлись, и на кнопке стало возможным писать и рисовать. Но остался фон самой кнопки, который полностью закрасить не удалось.
Следующим шагом поменял Appearance c Normal на Buttons, был еще вариант FlatButtons, но через конструктор его поставить не удалось, а выставление в коде ни на что не повлияло.
В режиме Buttons вылезла такая ерунда:
На картинке видно, что между кнопками и набором TabPages появилось расстояние. Отуда оно взялось и каким параметром регулируется, мне выяснить так и не удалось.
Еще некоторое время я изучал существующие платные и бесплатные библиотеки контролов на наличие возможности изменения под себя вкладок TabControl, но они либо предлагали использовать заранее созданные стили, либо позволяли максимум поменять цвет.
В итоге намучившись с ним, я решил написать свой контрол, взяв за основу стандартный. Целью стало скрыть стандартные вкладки и на смену им поставить свои, завязав их на контрол.
Постараюсь подробно описать все, что для этого пришлось сделать.
Шаг 1
Для начала в проекте нужно создать новый котрол. Для этого в панели Solution Explorer кликаем правой кнопкой по проекту, далее Add->Component, в открывшейся панели вводим имя нового контрола (у меня это NewTabControl)
Шаг 2
После создания открываем код созданного контрола. В коде делаем следующие правки:
дописываем
using System.Windows.Forms;
using System.Drawing;
Создаем три класса, наследуя их от классов стандартных контролов.
Класс нового TabControl
public partial class NewTabControl: System.Windows.Forms.TabControl
Класс нового контрола
public class NewTabPanel: System.Windows.Forms.Panel
Класс одной вкладки
public class PanelTP: System.Windows.Forms.Panel
Теперь нам нужно перезагрузить следующий метод в классе NewTabControl:
protected override void WndProc(ref Message m) { if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1; else base.WndProc(ref m); }
Данное действие позволит нам скрыть стандартные вкладки.
Теперь нам нужно связать все классы между собой. Не буду описывать весь код, его я приложу к данной статье. Опишу только самые интересные моменты.
Шаг 3
Компонуем все элементы в классе NewTabPanel:
private void InitializeComponent() { this.panel2 = new System.Windows.Forms.Panel(); //Панель с вкладками this.tabControl = new NewTabControl(); this.Controls.Add(this.tabControl); this.Controls.Add(this.panel2); this.Size = new System.Drawing.Size(311, 361); this.panel2.Dock = System.Windows.Forms.DockStyle.Left; this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill; tabControl.ControlAdded += new ControlEventHandler(tc_ControlAdded); //Событие на создание новой вкладки tabControl.ControlRemoved += new ControlEventHandler(tc_ControlRemoved); //Событие удаления вкладки tabControl.Selected += new TabControlEventHandler(tc_Selected); //Событие выделения вкладки }
Шаг 4
Теперь можно задать формат, как будет выглядеть сама вкладка.
На данном этапе вы можете сами расположить текст, картинку или любой другой элемент на будущей вкладке. А также задать размер и фон самой вкладки.
У себя я вывожу иконку и название вкладки.
В классе PanelTP создаем метод:
private void InitializeComponent() { this.Height = 27; this.Width = 128; this.BackgroundImage = Tabpanel.Properties.Resources.tab_c_74; this.Click += new EventHandler(Select_Item); PictureBox Icon; Icon = new PictureBox(); Icon.Width = 25; Icon.Height = 26; Icon.Left = 3; Icon.Top = 5; Icon.Image = Tabpanel.Properties.Resources.green_dialbut_611; this.Controls.Add(Icon); Label lname; lname = new Label(); lname.Width = 95; lname.Height = 25; lname.Left = 28; lname.Top = 5; lname.Font = new System.Drawing.Font("Times New Roman", 8f, FontStyle.Regular); lname.Text = this.name; lname.Click += new EventHandler(Select_Item); this.Controls.Add(lname); }
Шаг 5
Не буду описывать методы, обрабатывающие события, они подробно описаны в приложенном проекте. Перейду к применению.
После того как мы все сохранили, на панели Toolbox появятся новые компоненты
Теперь мы можем его разместить в нашей форме как захотим.
Чтобы добавить вкладку используем:
newTabPanel1.TabPages.Add("TabName");
Чтобы удалить:
newTabPanel1.TabPages.Remove(newTabPanel1.TabPages[id])
Где id — это номер вкадки
При такой реализации TabControl вы всегда сможете настроить сортировку между вкладками или скрыть выбранную вкладку, сделать вкладку любого размера и оформления, сделать панель с вкладками соврачиваемой и разворачиваемой.
По такому же принципу вы можете создать любой свой контрол скомпоновав и запрограммировав его из имеющихся.
Возможно, для кого-то я описал очевидные вещи, но надеюсь, найдутся и те, кому данная статья будет полезна.
ссылка на оригинал статьи http://habrahabr.ru/post/170375/