Button aus drei Bitmaps

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Button aus drei Bitmaps

    Und zwar habe ich einen Code um einen Button zu zeichnen.
    Dieser Button wird mithilfe von insgesamt 9 Bitmaps gezeichnet.
    3 Bitmaps setzen den Button zusammen und es gibt 3 Zustände (Clicked, Normal und Hover).

    Ich weiß, dass es prinzipiell schlecht ist Controls per Bitmaps zu zeichnen und man
    eher nur per GDI ohne Bitmaps zeichnen sollte. Dennoch
    wollte ich mal fragen, was man an dem folgenden Code noch verbessern könnte.

    Es wäre sehr nett, wenn ihr wirklich alles nennen könntet, was man besser machen könnte
    an diesem Code (außer den Einwurf, den Button ohne Bitmaps zu zeichnen).

    Danke im Voraus.

    C#-Quellcode

    1. ​[DefaultEvent("Click")] public class FakeMacButton : Control
    2. {
    3. private State CurrSt = State.Normal;
    4. private struct ButtonState
    5. {
    6. public readonly Bitmap Li,Mi,Ri;
    7. public ButtonState(Bitmap left, Bitmap middle, Bitmap right)
    8. {
    9. this.Li = left;
    10. this.Mi = middle;
    11. this.Ri = right;
    12. }
    13. }
    14. private ButtonState[] buttonStates =
    15. {
    16. new ButtonState(MangoETheme.Properties.Resources.MacBtnLeft, MangoETheme.Properties.Resources.MacBtnMiddle, MangoETheme.Properties.Resources.MacBtnRight),
    17. new ButtonState(MangoETheme.Properties.Resources.MacBtnLeftEntered, MangoETheme.Properties.Resources.MacBtnMiddleEntered, MangoETheme.Properties.Resources.MacBtnRightEntered),
    18. new ButtonState(MangoETheme.Properties.Resources.MacBtnLeftPressed, MangoETheme.Properties.Resources.MacBtnMiddlePressed, MangoETheme.Properties.Resources.MacBtnRightPressed)
    19. };
    20. public enum State : short
    21. {
    22. Normal = 0,
    23. Entered = 1,
    24. Down = 2
    25. }
    26. public FakeMacButton()
    27. {
    28. this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true);
    29. this.UpdateStyles();
    30. this.MinimumSize = new Size(53, 20);
    31. }
    32. public void Redraw(Graphics gr)
    33. {
    34. ButtonState buttonState = buttonStates[(int) CurrSt];
    35. gr.DrawImage(buttonState.Li, 0, 0, buttonState.Li.Width, this.Height);
    36. for (int i = buttonState.Li.Width; i <= this.Width - buttonState.Ri.Width - 1; i++) {
    37. gr.DrawImage(buttonState.Mi, i, 0, buttonState.Mi.Width, this.Height);
    38. }
    39. gr.DrawImage(buttonState.Ri, this.Width - buttonState.Ri.Width, 0, buttonState.Ri.Width, this.Height);
    40. SizeF textSize = this.CreateGraphics().MeasureString(Text, Font, Width - 4);
    41. StringFormat sf = new StringFormat() {LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center};
    42. gr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
    43. gr.DrawString(Text, Font, Brushes.Black, new RectangleF(2, 2, this.Width - 5, this.Height - 4), sf);
    44. }
    45. protected override void OnTextChanged(EventArgs e)
    46. {
    47. base.OnTextChanged(e);
    48. Invalidate();
    49. }
    50. public override Font Font
    51. {
    52. get {return base.Font;}
    53. set
    54. {
    55. if (base.Font.Equals(value)) return;
    56. base.Font = value;
    57. Invalidate();
    58. }
    59. }
    60. [Browsable(true), EditorBrowsable(EditorBrowsableState.Always), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    61. public override Color ForeColor
    62. {
    63. get { return Color.Empty; }
    64. set {
    65. if (base.ForeColor.Equals(value)) return;
    66. base.ForeColor = value;
    67. Invalidate();
    68. }
    69. }
    70. protected override void OnMouseDown(MouseEventArgs mevent)
    71. {
    72. CurrSt = State.Down;
    73. this.Invalidate();
    74. base.OnMouseDown(mevent);
    75. }
    76. protected override void OnMouseEnter(EventArgs e)
    77. {
    78. CurrSt = State.Entered;
    79. this.Invalidate();
    80. base.OnMouseEnter(e);
    81. }
    82. protected override void OnLeave(EventArgs e)
    83. {
    84. CurrSt = State.Normal;
    85. this.Invalidate();
    86. base.OnLeave(e);
    87. }
    88. protected override void OnMouseLeave(EventArgs e)
    89. {
    90. CurrSt = State.Normal;
    91. this.Invalidate();
    92. base.OnMouseLeave(e);
    93. }
    94. protected override void OnMouseUp(MouseEventArgs mevent)
    95. {
    96. CurrSt = State.Entered;
    97. this.Invalidate();
    98. base.OnMouseUp(mevent);
    99. }
    100. protected override void OnPaint(PaintEventArgs pevent){Redraw(pevent.Graphics);}
    101. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Daniel Baumert“ ()

    Daniel Baumert schrieb:

    verbessern
    Bei Font.Set kannst Du noch einen Equals-Test einfügen (wie bei ForeColor).

    Daniel Baumert schrieb:

    C#-Quellcode

    1. Graphics gr = ausgabe;
    Was soll diese überflüssige Variable in Redraw()?
    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!
    Das mit dem Invalid beim TextChanged habe ich reingemacht, damit man sofern man
    im Designer den Text ändert direkt sehen kann, wie es aussieht.
    Ansonsten wirds erst gezeichnet wenn man mit der Maus auf die Form klickt und nicht unverzüglich.

    Wofür ist denn MeasureStrin gut? Kann ich das hier evtl. anwenden
    und somit eine Konstante ersetzen?


    Mit

    Daniel Baumert schrieb:

    MeasureString
    erhältst Du die Größe eines Textes entsprechend Graphics und Font, das brauchst Du, wenn Du von Hand Texte zusammensetzt oder das Um-Rechteck benötigst.
    Wenn Du es nicht verwendest - raus damit.
    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!