Ecke in Form abrunden

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

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Yanbel.

    Ecke in Form abrunden

    Hallo Habe mal eine frage habe dazu zwar was gefunden aber ich versuche nur eine ecke rundzumachen weis aber net wie


    Den code verwende ich

    VB.NET-Quellcode

    1. Sub abrunden(ByVal was As Object,
    2. ByVal x As Integer, ByVal y As Integer,
    3. ByVal width As Integer, ByVal height As Integer,
    4. ByVal radius As Integer)
    5. Dim gp As System.Drawing.Drawing2D.GraphicsPath =
    6. New System.Drawing.Drawing2D.GraphicsPath()
    7. gp.AddLine(x + radius, y, x + width - radius, y)
    8. gp.AddArc(x + width - radius, y, radius, radius, 270, 90)
    9. gp.AddLine(x + width, y + radius, x + width, y + height - radius)
    10. gp.AddArc(x + width - radius, y + height - radius, radius, radius, 0, 90)
    11. gp.AddLine(x + width - radius, y + height, x + radius, y + height)
    12. gp.AddArc(x, y + height - radius, radius, radius, 90, 90)
    13. gp.AddLine(x, y + height - radius, x, y + radius)
    14. gp.AddArc(x, y, radius, radius, 180, 90)
    15. gp.CloseFigure()
    16. was.region = New System.Drawing.Region(gp)
    17. gp.Dispose()
    18. End Sub



    VB.NET-Quellcode

    1. abrunden(Me, 0, 0, Me.Width, Me.Height, 40)



    Jetzt ist die frage wie krige ich nur eine ecke rund oder eher gesagt eine mehr als die andere

    @Nico(Nano.exe), ich war so frei einen besseren Titel zu vergeben. Was hat das aktuelle Jahr mit deinem Problem zu tun? Bitte das nächste mal mehr Gedanken machen. Grüße ~NoFear23m

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

    Indem Du verstehst, was der Code macht und ihn dann an Deine Wünsche anpasst?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Du hast 4x AddArc, baust also an 4 Stellen einen Bogen ein. Ein GraphicsPath fängt bei einem Punkt an und man sagt dem Compiler eben, wie es von dort weitergeht. Daher wäre es eben sinnvoll, dass Du einmal AddArc hast und dann eben 2-3 gerade Linien, ggf. mit CloseFigure abschließen. Mal den GraphicsPath ggf. Schritt für Schritt als grafisches Objekt, anstatt es als Formaußenrand zu verwenden, dann kommst Du sicherlich schneller zum Ziel, weil Du nach jeder zugeschalteten Anweisung verstehst, was diese mit der Gesamtfigur macht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Nico(Nano.exe) Experimentiere mit den Parametern der Prozedur, da bekommst Du ein Gefühl, was da passiert.
    Einmal kannst Du von außen andere Werte vorgeben, zum anderen kannst Du innerhalb der Prozedur einzelne Ecken anders behandeln, z.B. den Radius verdoppeln.
    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!
    Ich hab da mal ne Frage: Wieso gehst du über die Form.Region? hier beschneidest du dich selbst in deinen Möglichkeiten, da du auf die Regions kein AntiAliasing anwenden kannst und abgerundete Ecken verpixelt ausgegeben werden. Das zu smoothen ist mit Regions echt kein Vergnügen. Stattdessen würde ich wie folgt vorgehen:

    VB.NET-Quellcode

    1. Private Sub FormAbrunden()
    2. gPathForm = New GraphicsPath
    3. gPathForm.StartFigure()
    4. gPathForm.AddArc(New Rectangle(0, 0, 60, 60), 180, 90)
    5. gPathForm.CloseFigure()
    6. gPathForm.StartFigure()
    7. gPathForm.AddRectangle(New Rectangle(30, 0, Width - 30, Height))
    8. gPathForm.CloseFigure()
    9. gPathForm.StartFigure()
    10. gPathForm.AddRectangle(New Rectangle(0, 30, Width, Height - 30))
    11. gPathForm.CloseFigure()
    12. gPathForm.StartFigure()
    13. gPathForm.AddPolygon({New Point(0, 30), New Point(30, 0), New Point(30, 30)})
    14. gPathForm.CloseFigure()
    15. gPathForm.FillMode = FillMode.Winding
    16. End Sub


    Und dann im PaintEvent:

    VB.NET-Quellcode

    1. 'Methodenaufruf
    2. FormAbrunden()
    3. 'Antialiasing festlegen
    4. e.Graphics.SmoothingMode = SmoothingMode.HighQuality
    5. 'BackColor mit einer Farbe belegen, die nirgendwo sonst verwendet wird!!!
    6. BackColor = Color.FromArgb(255, 32, 32, 32)
    7. 'TransparencyKey auf BackColor festlegen, damit erstmal alles transparent wird
    8. TransparencyKey = Color.FromArgb(255, 32, 32, 32)
    9. 'Alles mit gewünschtem GraphicsPath und BackColor überpinseln
    10. e.Graphics.FillPath(New SolidBrush(Color.White), gPathForm)
    11. 'Optional kannst du danach auch die Region noch setzen
    12. Region = New Region(gPathForm)

    Bilder
    • RundedEdgeForm.PNG

      3,89 kB, 819×557, 78 mal angesehen


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Yanbel“ ()

    *Antwort auf gelöschtes Posting entfernt*

    @Yanbel: Mit jedem Paint-Event die Regions neu kreieren und dem Form als Region zuordnen? N bisken Overkill, oder? Dann vielleicht (!) noch eher den GraphicsPath speichern und ihn nur noch im Paint-EventHandler anwenden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Ich programmiere ja auch schon eine Weile, aber wie es so ist, gibt es Bereiche die ich nie auch nur ansatzweise berührt habe.
    Aber ich weiß, dass bei Winforms die GUI über Ereignisse (Events) gesteuert wird. Freundlicherweise, oder Dummerweise hilft einem die GUI dabei so sehr, dass man den Begriff selbst kaum kennen muss, wenn man sich die Ereignisse so ansieht, fallen einem vielleicht Begriffe wie EventArgs auf, vielleicht aber auch nicht.

    Nun schreibt aber @Yanbel von der Form, konkret von der Methode / Funktion FormAbrunden. Wenn man jetzt noch im VS in den Eigenschaften der Form nachschaut, welche Ereignisse man buchen kann, käme man schon dahinter, welches Event, sorry.. Ereignis es sein könnte.
    Was @Yanbel aber nicht schreibt ist, dass man die Variable gPathForm erst einmal definieren muss, Private für die Form selbst. Dann steht da auch nichts davon, dass die Form wohlmöglichst keinen Rahmen (Border) haben sollte, damit das Ergebnis auch toll aussieht. Dann kommen die nächsten Probleme, wie baue ich den Rahmen und die ControlBox oder wenigstens eine "Beenden"-Möglichkeit in die Form ein.
    Also Fragen über Fragen und IMO für den OP zu harter Tobak.
    Mit jedem Paint-Event die Regions neu kreieren und dem Form als Region zuordnen? N bisken Overkill, oder? Dann vielleicht (!) noch eher den GraphicsPath speichern und ihn nur noch im Paint-EventHandler anwenden.


    @VaporiZed: Mache ich normalerweise im Resize-Event und verwende im Paint-Event nur noch das fertige GraphicsPath. Für das aber verweise ich auf den vorangegangenen Post von @FormFollowsFunction: Der TE hast sich hier bisher nicht mit Ruhm bekleckert, was Eigeninitiative angeht. Und von daher kriegt er eine Lösung die funktioniert und nicht die Top-Lösung. Im Normalfall hätte ich ihm auch WinForms mit Viewmodel ans Herz gelegt in welchem er dutzende Beispiele findet, die exakt so aufgebaut sind, wie du es gerade beschrieben hast. Aber seien wir mal ehrlich, wer nicht mal nach Paint-Event googlt, sondern lieber eine Frage in einem Forum postet... der Satz bedarf glaube ich keiner Weiterführung.

    @Dksksm Vermutlich hast du Recht. Aufgrund seines Programmbeispiels hatte ich angenommen, dass er grundlegende Kenntnisse in diesen Bereichen besitzt.
    gPathForm habe ich nicht extra beschrieben, weil der Typ klar ist (siehe: gPathForm = New GraphicsPath) und dass man um eine Variable in zwei Methoden verwenden zu können, diese klassenweit deklarieren muss, setze ich für jemanden der sich mit Regions beschäftigt als Grundkenntnis voraus. Und ja, die Form sollte Borderless sein, für den Fall dass er den Code wie ich auf eine Form anwenden will.

    Dann steht da auch nichts davon, dass die Form wohlmöglichst keinen Rahmen (Border) haben sollte, damit das Ergebnis auch toll aussieht. Dann kommen die nächsten Probleme, wie baue ich den Rahmen und die ControlBox oder wenigstens eine "Beenden"-Möglichkeit in die Form ein.

    Wenn er eine Ecke abrunden will, dann sollte der TE zwangläufig wissen, wie man hier vorgeht. Ansonsten sollte er die Form vielleicht lieber eckig lassen :D


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Yanbel“ ()