Управление вертикальной вкладкой с горизонтальным текстом в Winforms
Я хотел бы, чтобы вкладки на моем TabControl отображались слева, или иногда справа.
В отличие от системы.Окна.Формы.TabControl, однако, я хотел бы, чтобы текст оставался горизонтальным, а не поворачивался на 90 или 270 градусов к горизонтали.
вот несколько фотографий, иллюстрирующих концепцию
хотя я мог бы написать код, чтобы сделать это сам примерно через час или два, я просто подумал, что сначала спрошу, если существует любой существующий элемент управления Winforms, который реализует такую функцию.
NB: любое существующее решение должно быть предпочтительно некоммерческим.
спасибо.
4 ответов
Я не знаю, насколько это надежно, и я не могу утверждать, что создал его, но... http://www.dreamincode.net/forums/topic/125792-how-to-make-vertical-tabs/
вот способ сделать это.
поэтому сначала мы изменим его выравнивание влево, установив свойство:
Выравнивание = Левый
Если у вас включены темы XP, вы можете заметить странный макет элемента управления вкладками. Не волнуйся, мы справимся. штраф.
Как вы могли заметить, вкладки вертикальные, а наше требование горизонтальное. Таким образом, мы можем изменить размер вкладок. Но прежде чем мы сможем это сделать, мы должны установить свойство SizeMode как,
SizeMode = Фиксированная
теперь мы можем изменить размер, используя свойство ItemSize,
ItemSize = 30, 120 Ширина = 30 и высота = 120
после установки выравнивание = слева, вкладка поворот Вкладки, которые вызывают ширину и высоту, кажутся обратными. Вот почему, когда мы увеличиваем высоту, мы видим, что ширина увеличивается, а когда мы увеличиваем ширину, высота достигается.
теперь текст также будет отображаться, но вертикально. К сожалению, нет простого способа решить эту проблему. Для этого мы должны написать текст сами. Для этого мы сначала установим DrawMode
DrawMode = OwnerDrawFixed
01
Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
Dim g As Graphics
Dim sText As String
Dim iX As Integer
Dim iY As Integer
Dim sizeText As SizeF
Dim ctlTab As TabControl
ctlTab = CType(sender, TabControl)
g = e.Graphics
sText = ctlTab.TabPages(e.Index).Text
sizeText = g.MeasureString(sText, ctlTab.Font)
iX = e.Bounds.Left + 6
iY = e.Bounds.Top + (e.Bounds.Height - sizeText.Height) / 2
g.DrawString(sText, ctlTab.Font, Brushes.Black, iX, iY)
End Sub
Я решил поделиться код, который я разработал, так как некоторые люди, такие как Амит Andharia, хотели бы извлечь из этого пользу.
Это результат после того, как я реализовал ответ Роба П..
Заметки:
- полная поддержка во время разработки
- автоматическое изменение размера вкладок (до 128 пикселей в ширину)
- вкладка иконки выполнены
- неиспользованный свойства были скрыты
код можно загрузить из здесь.
Это код для пользовательского элемента управления вкладками, который мне очень нравится. Вам нужно будет скопировать и вставить этот код в новый класс, затем перестройте проект. В панели инструментов появится новый пользовательский элемент управления.
Imports System.Drawing.Drawing2D
Class DotNetBarTabcontrol
Inherits TabControl
Sub New()
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.ResizeRedraw Or ControlStyles.UserPaint Or ControlStyles.DoubleBuffer, True)
DoubleBuffered = True
SizeMode = TabSizeMode.Fixed
ItemSize = New Size(44, 136)
End Sub
Protected Overrides Sub CreateHandle()
MyBase.CreateHandle()
Alignment = TabAlignment.Left
End Sub
Function ToPen(ByVal color As Color) As Pen
Return New Pen(color)
End Function
Function ToBrush(ByVal color As Color) As Brush
Return New SolidBrush(color)
End Function
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim B As New Bitmap(Width, Height)
Dim G As Graphics = Graphics.FromImage(B)
Try : SelectedTab.BackColor = Color.White : Catch : End Try
G.Clear(Color.White)
G.FillRectangle(New SolidBrush(Color.FromArgb(246, 248, 252)), New Rectangle(0, 0, ItemSize.Height + 4, Height))
'G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(Width - 1, 0), New Point(Width - 1, Height - 1)) 'comment out to get rid of the borders
'G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(ItemSize.Height + 1, 0), New Point(Width - 1, 0)) 'comment out to get rid of the borders
'G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(ItemSize.Height + 3, Height - 1), New Point(Width - 1, Height - 1)) 'comment out to get rid of the borders
G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(ItemSize.Height + 3, 0), New Point(ItemSize.Height + 3, 999))
For i = 0 To TabCount - 1
If i = SelectedIndex Then
Dim x2 As Rectangle = New Rectangle(New Point(GetTabRect(i).Location.X - 2, GetTabRect(i).Location.Y - 2), New Size(GetTabRect(i).Width + 3, GetTabRect(i).Height - 1))
Dim myBlend As New ColorBlend()
myBlend.Colors = {Color.FromArgb(232, 232, 240), Color.FromArgb(232, 232, 240), Color.FromArgb(232, 232, 240)}
myBlend.Positions = {0.0F, 0.5F, 1.0F}
Dim lgBrush As New LinearGradientBrush(x2, Color.Black, Color.Black, 90.0F)
lgBrush.InterpolationColors = myBlend
G.FillRectangle(lgBrush, x2)
G.DrawRectangle(New Pen(Color.FromArgb(170, 187, 204)), x2)
G.SmoothingMode = SmoothingMode.HighQuality
Dim p() As Point = {New Point(ItemSize.Height - 3, GetTabRect(i).Location.Y + 20), New Point(ItemSize.Height + 4, GetTabRect(i).Location.Y + 14), New Point(ItemSize.Height + 4, GetTabRect(i).Location.Y + 27)}
G.FillPolygon(Brushes.White, p)
G.DrawPolygon(New Pen(Color.FromArgb(170, 187, 204)), p)
If ImageList IsNot Nothing Then
Try
If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then
G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x2.Location.X + 8, x2.Location.Y + 6))
G.DrawString(" " & TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
Else
G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Bold), Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
End If
Catch ex As Exception
G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Bold), Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
End Try
Else
G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Bold), Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
End If
G.DrawLine(New Pen(Color.FromArgb(200, 200, 250)), New Point(x2.Location.X - 1, x2.Location.Y - 1), New Point(x2.Location.X, x2.Location.Y))
G.DrawLine(New Pen(Color.FromArgb(200, 200, 250)), New Point(x2.Location.X - 1, x2.Bottom - 1), New Point(x2.Location.X, x2.Bottom))
Else
Dim x2 As Rectangle = New Rectangle(New Point(GetTabRect(i).Location.X - 2, GetTabRect(i).Location.Y - 2), New Size(GetTabRect(i).Width + 3, GetTabRect(i).Height + 1))
G.FillRectangle(New SolidBrush(Color.FromArgb(246, 248, 252)), x2)
G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(x2.Right, x2.Top), New Point(x2.Right, x2.Bottom))
If ImageList IsNot Nothing Then
Try
If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then
G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x2.Location.X + 8, x2.Location.Y + 6))
G.DrawString(" " & TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
Else
G.DrawString(TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
End If
Catch ex As Exception
G.DrawString(TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
End Try
Else
G.DrawString(TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
End If
End If
Next
e.Graphics.DrawImage(B.Clone, 0, 0)
G.Dispose() : B.Dispose()
End Sub
End Class
существует учебник, предоставленный Microsoft для этого с существующим TabControl на MSDN, С образцом кода, приведенным как в C#, так и в Visual Basic .Сеть. Их метод основан на использовании owner drawing. Резюмируя их шаги ниже:
установить элемент управления TabControl по трассы свойство право.
убедитесь, что все вкладки имеют одинаковую горизонтальную ширину, установив SizeMode свойство основные.
установить ItemSize свойство вашего предпочтительного размера для вкладок, имея в виду, что ширина и высота поменялись местами.
установить значение drawmode свойство OwnerDrawFixed.
-
настройка обработчика событий для Tabcontrol's DrawItem событие и поместите туда код чертежа владельца диктует, как должна отображаться каждая вкладка. Их пример кода C# для обработчика событий воспроизводится ниже для удобства (предполагается, что ваш TabControl называется
tabControl1
:private void tabControl1_DrawItem(Object sender, System.Windows.Forms.DrawItemEventArgs e) { Graphics g = e.Graphics; Brush _textBrush; // Get the item from the collection. TabPage _tabPage = tabControl1.TabPages[e.Index]; // Get the real bounds for the tab rectangle. Rectangle _tabBounds = tabControl1.GetTabRect(e.Index); if (e.State == DrawItemState.Selected) { // Draw a different background color, and don't paint a focus rectangle. _textBrush = new SolidBrush(Color.Red); g.FillRectangle(Brushes.Gray, e.Bounds); } else { _textBrush = new System.Drawing.SolidBrush(e.ForeColor); e.DrawBackground(); } // Use our own font. Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel); // Draw string. Center the text. StringFormat _stringFlags = new StringFormat(); _stringFlags.Alignment = StringAlignment.Center; _stringFlags.LineAlignment = StringAlignment.Center; g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags)); }
вы, вероятно, можете поэкспериментировать с вашим ItemSize
собственность и _tabFont
значение из приведенного выше кода, чтобы настроить внешний вид ваших вкладок на все, что вам нужно. Для еще более причудливого стиля я бы рекомендовал посмотреть на эта другая статья MSDN в качестве отправной точка.
(источник: как: отображение боковых выровненных вкладок с TabControl (MSDN))