Multiline-Reiter für TabControls

    • Allgemein

      Multiline-Reiter für TabControls

      Ziel war die Erstellung eines TabControls, dessen Reiter-Text über 2 Zeilen gehen kann (von hier):

      Mit tatkräftiger Hilfe von @us4711 und Mick Doherty wurde das Problem grundsätzlich gelöst.
      Allerdings war mir die Verwendung einer Hashtable zum Zwischenspeichern der Texte der zweiten Zeilen etwas oversized.
      Hier habe ich das Problem mit deutlich weniger Aufwand gelöst:
      C#-Code

      C#-Quellcode

      1. using System.Drawing;
      2. using System.Windows.Forms;
      3. namespace WindowsFormsApplication1
      4. {
      5. public partial class Form1 : Form
      6. {
      7. public Form1()
      8. {
      9. this.InitializeComponent();
      10. this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
      11. this.tabControl1.Padding = new Point(6, this.tabControl1.Font.Height);
      12. }
      13. private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
      14. {
      15. TabControl tabControl = (TabControl)sender;
      16. TabPage currentTab = tabControl.TabPages[e.Index];
      17. Graphics g = e.Graphics;
      18. StringFormat sf = new StringFormat();
      19. sf.Alignment = StringAlignment.Center;
      20. sf.LineAlignment = StringAlignment.Center;
      21. Rectangle tabRect = (Rectangle)e.Bounds;
      22. Rectangle textRect = tabRect;
      23. if (e.Index == tabControl.SelectedIndex)
      24. {
      25. tabRect.Inflate(1, 1);
      26. }
      27. g.Clip = new Region(tabRect);
      28. g.Clear(Control.DefaultBackColor);
      29. g.ResetClip();
      30. string tabText = currentTab.Text.Replace(@"\n", "\n");
      31. g.DrawString(tabText, e.Font, SystemBrushes.ControlText, textRect, sf);
      32. }
      33. }
      34. }
      VB-Code

      VB.NET-Quellcode

      1. Public Class Form1
      2. Public Sub New()
      3. InitializeComponent()
      4. Me.TabControl1.DrawMode = TabDrawMode.OwnerDrawFixed
      5. Me.TabControl1.Padding = New Point(6, Me.TabControl1.Font.Height)
      6. End Sub
      7. Private Sub TabControl1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles TabControl1.DrawItem
      8. Dim tabControl As TabControl = DirectCast(sender, TabControl)
      9. Dim currentTab As TabPage = tabControl.TabPages(e.Index)
      10. Dim g As Graphics = e.Graphics
      11. Dim sf As New StringFormat()
      12. sf.Alignment = StringAlignment.Center
      13. sf.LineAlignment = StringAlignment.Center
      14. Dim tabRect As Rectangle = e.Bounds
      15. Dim textRect As Rectangle = tabRect
      16. If e.Index = tabControl.SelectedIndex Then
      17. tabRect.Inflate(1, 1)
      18. End If
      19. g.Clip = New Region(tabRect)
      20. g.Clear(Control.DefaultBackColor)
      21. g.ResetClip()
      22. Dim tabText As String = currentTab.Text.Replace("\n", ControlChars.Lf)
      23. g.DrawString(tabText, e.Font, SystemBrushes.ControlText, textRect, sf)
      24. End Sub
      25. End Class
      Im Designer ist lediglich die Text-Umbruch-Stelle mit einem "\n" zu markieren:

      der Rest wird im Konstruktor eingetragen.
      Das Setzen der DrawMode-Property im Konstruktor und nicht im Designer sorgt dafür, dass die Reiter-Texte im Designer angezeigt werden, da das DrawItem-Event im Designer nicht aufgerufen wird.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!