BeveledLabel - Label wie in Installern

    • C#
    • .NET (FX) 1.0–2.0

    Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Nikx.

      BeveledLabel - Label wie in Installern

      Hallo Community,
      Ich möchte euch hier mal den SourceCode für ein BeveledLabel zur verfügung stellen.

      Was ist eine BeveledLabel?
      Das BeveledLabel ist ein Label mit einem darauffolgendem Strich, wie es in Installern der Fall ist. Siehe Screen:

      Quelle: Installer für Notepad++ 6.8.8

      SourceCode:
      Verweise

      Verweise braucht ihr für:
      - System.Drawing
      - System.Windows.Forms
      - System.ComponentModel

      Beveled Designer Klasse

      Diese Klasse braucht ihr, um dem ControlDesigner zu sagen das man nur Bestimmte auswahlmöglichkeiten hat

      C#-Quellcode

      1. using System.Windows.Forms.Design;
      2. internal class BeveledDesigner : ControlDesigner
      3. {
      4. public override SelectionRules SelectionRules
      5. {
      6. get
      7. {
      8. return SelectionRules.Moveable | SelectionRules.RightSizeable;
      9. }
      10. }
      11. }



      BeveledLabel ControlKlasse

      Kommentare stehen vor dem Code :)

      C#-Quellcode

      1. using System;
      2. using System.ComponentModel;
      3. using System.Windows.Forms;
      4. using System.Drawing;
      5. using System.Drawing.Drawing2D;
      6. using System.Windows.Forms.Design;
      7. using System.Windows.Forms.VisualStyles;
      8. //Designer Eigenschaften
      9. [DesignerCategory("Code")]
      10. [Designer(typeof(BeveledDesigner))]
      11. [DisplayName("BeveledLabel")]
      12. [DefaultProperty("Text")]
      13. [DefaultEvent("ActivateBeveled")]
      14. [Description("Ein Label gefolgt von einer beliebig langen Linie, wie es bei vielen Setups der fall ist..")]
      15. [ToolboxItem(true)]
      16. [ToolboxBitmap(typeof(GroupBox))]
      17. public class BeveledLabel : Control
      18. {
      19. //Beim Initializieren des Labels
      20. public BeveledLabel()
      21. {
      22. //Den Wert fürs Initializieren setzen
      23. initializing = true;
      24. //Schrift ändern
      25. this.Font = new Font("Segoe UI", 9, FontStyle.Regular);
      26. int size = (int)(this.Font.Height);
      27. if (istGerade(size)) { size++; }
      28. this.Size = new Size(this.Size.Width * 3, size);
      29. thisHeight = this.Size.Height;
      30. //Deklarieren der Event-Funktionen
      31. this.Paint += BeveledLabel_Paint;
      32. this.FontChanged += BeveledLabel_FontChanged;
      33. this.SizeChanged += BeveledLabel_SizeChanged;
      34. this.Click += BeveledLabel_Click;
      35. //Den Wert auf False setzen, damit die Funktionen wissen, das es sich jetzt nichtmehr um die Initializierung handelt, die Werte festlegt.
      36. initializing = false;
      37. }
      38. //Wichtige Deklarationen
      39. bool initializing = false;
      40. int thisHeight = 13;
      41. //Deklarieren des EventHandlers
      42. public event EventHandler ActivateBeveled;
      43. //Das Event, in dem geprüft wird ob die Größe manuell oder automatisch geändert wurde
      44. void BeveledLabel_SizeChanged(object sender, EventArgs e)
      45. {
      46. //Prüfen ob das BeveledLabel in der Initializierungsphase ist
      47. if (initializing != false)
      48. {
      49. //Dann prüfen ob die Höhe auch die ist, die es seien muss.
      50. if (this.Size.Height != thisHeight)
      51. {
      52. //Falls nicht, zurücksetzen und einen ArgumentOutOfRange Fehler ausgeben.
      53. this.Size = new Size(this.Size.Width, thisHeight);
      54. throw new ArgumentOutOfRangeException("Du kannst die Größe nicht manuell ändern, da diese automatisch vergeben wird");
      55. }
      56. }
      57. }
      58. //Aktivierung des Controleigenen Events. Eigentlich unnötig, aber warum denn nicht ? :)
      59. void BeveledLabel_Click(object sender, EventArgs e)
      60. {
      61. ActivateBeveled(this, EventArgs.Empty);
      62. }
      63. //Funktion, zum Prüfen ob eine Zahl gerade ist oder nicht.
      64. private bool istGerade(int Zahl)
      65. {
      66. return Zahl % 2 == 0;
      67. }
      68. //Bei änderung der Font, die Größe ändern
      69. void BeveledLabel_FontChanged(object sender, EventArgs e)
      70. {
      71. //Höhe der Schriftart herausfinden
      72. int size = (int)(this.Font.Height);
      73. //Prüfen ob die Zahl gerade ist, falls ja wird 1 dazuadiert, um sicherzugehen das es eine ungerade Zahl ist.
      74. //Eine ungerade Zahl deswegen, da man sonst keine Mitte hat.
      75. if (istGerade(size)) { size++; }
      76. //Höhe in Variable festlegen
      77. thisHeight = this.Size.Height;
      78. //Größe ändern
      79. this.Size = new Size(this.Size.Width, size);
      80. }
      81. //Zeichen des Controls
      82. void BeveledLabel_Paint(object sender, PaintEventArgs e)
      83. {
      84. //Erzeugen eines Pens, zum Zeichen
      85. Pen p = new Pen(new SolidBrush(this.ForeColor), 1F);
      86. //Die Hälfte der Höhe herausfinden, um die Linie genau in die Mitte zu zeichnen
      87. int pHalf = this.Size.Height;
      88. //Toleranz abziehen
      89. pHalf--;
      90. //Hälfte ausrechnen
      91. pHalf = pHalf / 2;
      92. //Toleranz draufrechnen
      93. pHalf++;
      94. //Messen der Breite des Textes, um zu wissen, ab wann die Linie gezeichnet werden soll. Nicht das die Linie den Text durchstreicht.
      95. int breite = (int)e.Graphics.MeasureString(this.Text, this.Font, this.Size.Width).Width;
      96. //Text vor der Linie zeichnen
      97. e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), new Point(0, 0));
      98. //Linie nach dem Text zeichnen
      99. e.Graphics.DrawLine(p, new Point(breite, pHalf), new Point(this.Size.Width - 1, pHalf));
      100. //Ressourcen wieder freigeben
      101. p.Dispose();
      102. e.Graphics.Dispose();
      103. e.Dispose();
      104. }
      105. }



      Und für die, die zu faul sind das einfache C&P (Copy und Paste) zu verwenden,
      Hier ein TestProjekt

      Für ein Feedback oder eine Hilfreich Bewertung (wenn es Hilfreich war) würd ich mich freuen

      ManuelSoftware schrieb:

      bool initializing = false;

      ManuelSoftware schrieb:

      initializing = true;
      Warum setzt Du den Wert nicht direkt?

      ManuelSoftware schrieb:

      public event EventHandler ActivateBeveled;
      HIerfür würde ich immer den generischen EventHandler benutzen. Geht hier auch so, ist aber imo schöner. Das Event würde ich auch BTW eher BeveledActivated nennen.

      ManuelSoftware schrieb:

      if (initializing != false)
      Was ist denn das? Einfach if (initializing).

      ManuelSoftware schrieb:

      //Falls nicht, zurücksetzen und einen ArgumentOutOfRange Fehler ausgeben.
      Halte ich für unlogisch. Warum setzt Du die Größe zurück, wenn dann doch eh eine Exception geschmissen wird? Das ist dann ja redundant. Wobei ich hier dann lieber verhindern würde, dass die Höhe gesetzt werden kann, ohne eine Exception zu schmeißen. Das wäre imho schöner.

      ManuelSoftware schrieb:

      Pen p = new Pen(new SolidBrush(this.ForeColor), 1F);
      Du gibst Deine Brush nirgends frei, nur den Pen. Ich würde hier verschachtelte Using-Anweisungen verwenden.

      ManuelSoftware schrieb:

      private bool istGerade(int Zahl)
      Durchgehende Nomenklatur beachten!

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Die Benennungen gehören durchgehend englisch.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Moin,
      was kann dein Code mehr als das hier?

      C#-Quellcode

      1. public class LineLabel : Control {
      2. public LineLabel () {
      3. this.Paint += DrawLabel;
      4. }
      5. public Color TextColor { get; set; } = Color.Black;
      6. public Color LineColor { get; set; } = Color.LightGray;
      7. public int LineMargin { get; set; } = 5;
      8. private void DrawLabel (object sender, PaintEventArgs e) {
      9. var g = e.Graphics;
      10. var stringDimensions = g.MeasureString (Text, this.Font);
      11. this.Height = (int)stringDimensions.Height;
      12. g.DrawString (Text, this.Font, new SolidBrush (TextColor), new Point (0, 0));
      13. g.DrawLine (new Pen (new SolidBrush (LineColor)), new PointF (stringDimensions.Width + LineMargin, stringDimensions.Height / 2), new PointF (this.Width, stringDimensions.Height / 2));
      14. g.Dispose ();
      15. }
      16. }


      Grüße
      "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

      Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
      g.Dispose() ist keine gute Idee. Auch das Event braucht man nicht abonnieren - einfach Label beerben und OnPaint überschreiben:

      C#-Quellcode

      1. [DesignerCategory("Code")]
      2. public class BevelLable : Label {
      3. protected override void OnPaint(PaintEventArgs e) {
      4. base.OnPaint(e);
      5. var left = e.Graphics.MeasureString(Text, Font).Width;
      6. var top = Height / 2;
      7. using (var p = new Pen(ForeColor)) e.Graphics.DrawLine(p, left, top, short.MaxValue, top);
      8. }
      9. }
      Alternativ braucht man auch gar kein eigenes Control, sondern setzt den gezeigten Code einfach in den Paint-Eventhandler eines beliebigen Labels.

      C#-Quellcode

      1. private void label1_Paint(object sender, PaintEventArgs e) {
      2. var ctr = (Control)sender;
      3. var left = e.Graphics.MeasureString(ctr.Text, ctr.Font).Width;
      4. var top = ctr.Height / 2;
      5. using (var p = new Pen(ctr.ForeColor)) e.Graphics.DrawLine(p, left, top, short.MaxValue, top);
      6. }
      Das geht sogar mit beliebigen Controls - nicht nur Label.
      Dateien
      • BeveledTest.zip

        (34,86 kB, 168 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

      @ErfinderDesRades Der Code ist schon etwas älter, könnte ich wohl mal überarbeiten. Trotzdem finde ich den Originalcode des TE zu immens.
      "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

      Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!