GDI / neu hinzugekommenen Bereich zeichnen

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 43 Antworten in diesem Thema. Der letzte Beitrag () ist von mrMo.

    @mrMo Mach das bei einem normalen Button und lies die Flags aus, wenn das geht.
    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!

    RodFromGermany schrieb:

    lies die Flags aus, wenn das geht.

    ​Wie/wo könnte man die ermitteln?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @mrMo Jou, das passiert ja im Paint.
    Sieh Dir mal die Prozedur OnPaint im IlSpy an.
    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!
    zunächstmal: Dein SuperButton ist kein UserControl.
    Mach mal Menü-Projekt-Hinzufügen-UserControl, dann weisst du was ein UserControl ist.
    Was du gebastelt hast, bezeichnet man als CustomControl.

    Dann: Lass doch einfach die Finger von der Text-Property. Setze die wie gewohnt, und dann funzt auch das Klicksen beim Drücken des Accessor-Keys.

    Konzentriere dich einzig aufs Zeichnen des Buttons - dabei kannst du ja auch auf die Text-Property zurückgreifen - die erbst du ja.
    Also führe keine zusätzlichen Properties ein, wenn es deren Funktionalität bereits gibt.

    Das Zeichnen eines guten Button ist übrigens ziemlich kompliziert - ist dir schonmal aufgefallen, dass ein focussierter Button anders aussieht, und im gedrückten Zustand nochmal anders?

    RodFromGermany schrieb:

    im IlSpy an.


    ​Ja da könnt ich mal schauen, muss ich mal downloaden...
    Mal anders herum, wie nennt sich diese "&" Kiste eigentlich? Dann kann ich besser recherchieren.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Mnemonics, s. z.B. im MSDN
    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 „VaporiZed“ ()

    ErfinderDesRades schrieb:


    Was du gebastelt hast, bezeichnet man als CustomControl.

    Mag sein, hab damals eine WindowsFormsControlLibrary als Projekt angelegt.

    Dann: Lass doch einfach die Finger von der Text-Property.

    Dat Ding hat leider im Rohzustand keine Text-Property. Weil:
    die erbst du ja.

    Ne, will er nicht. Krieg ich die Meldung "Die Assembly (...) enthält keine UserControl-Typen"

    Weiß nicht, vielleicht mach ich das auch falsch?

    C#-Quellcode

    1. public partial class GlossyButton : System.Windows.Forms.Button


    Das Zeichnen eines guten Button ist übrigens ziemlich kompliziert

    Weiß ich, hab da schon allerlei Button Zustände drin. Ist alles etwas ausgeartet :)

    @VaporiZed Merci :)
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    mrMo schrieb:

    ... Weil:
    die erbst du ja.

    Ne, will er nicht. Krieg ich die Meldung "Die Assembly (...) enthält keine UserControl-Typen"
    Was will er nicht? Wer?
    Wenn dein CustomControl von Button erbt, dann hat es eine Text-Property. Kannste sogar im PropertyGrid des Designers nachgucken, wennde son Ding aufs Form ziehst.
    Die Meldung von wegen UserControl ist mir komplett unverständlich, weil du hast mit UserControl ja abgesehen von deiner Begriffsverwirrung garnichts zu schaffen.
    Von welcher Assembly ist da eiglich die Rede?

    mrMo schrieb:

    Weiß nicht, vielleicht mach ich das auch falsch?

    C#-Quellcode

    1. public partial class GlossyButton : System.Windows.Forms.Button
    Nein - genau richtig: Von Button erben.
    Und damit erbst du auch die Text-Property.
    Ganz sicher.
    @ErfinderDesRades

    Hab jetzt nochmal so ein Testprojekt erstellt (Projektmappe siehe Anhang):

    Ist das Kein UserControl?

    ​Dort erbe ich so vom Button:

    C#-Quellcode

    1. ​public partial class UserControl1: Button


    Beim kompilieren kommt (wie im echten Projekt) dann diese Meldung:
    Die Assembly "C:\Users\mrmo\Documents\Visual Studio 2015\Projects\GButton\GButton\obj\Debug\GButton.dll" enthält keine UserControl-Typen.
    Dateien
    • GButton.zip

      (23,25 kB, 98 mal heruntergeladen, zuletzt: )
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    mrMo schrieb:

    C#-Quellcode

    1. public partial class UserControl1: Button
    Warum heisst das Ding denn nun auf einmal UserControl1??
    Ich denke, es soll GlossyButton heissen?

    Willst du dich absichtlich verwirren?

    (Bei mir kompiliert dein Upload problemlos - es fehlt nur ein Testprojekt zum Testen - ist das Absicht?)

    ErfinderDesRades schrieb:

    Warum heisst das Ding denn nun auf einmal UserControl1??


    Das ist ein Beispiel aus meinem eben neu erstellten Testprojekt, welches ich hier hochgeladen habe, falls jemand den Effekt nachvollzeihen will.
    Im echten Projekt steht weiterhin

    C#-Quellcode

    1. public partial class GlossyButton : System.Windows.Forms.Button


    Edit: @ErfinderDesRades
    ​(Bei mir kompiliert dein Upload problemlos - es fehlt nur ein Testprojekt zum Testen - ist das Absicht?)

    ​Hab das Teil jetzt auch runter geladen und kompiliert. Bei mir kommt weiterhin dieser Fehler...
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Hier mal eine Vorlage mit Testprojekt und ohne jedes Brimborium.
    InitializeComponents, die DesignerDatei und die Resourcen sind nämlich nicht erforderlich und bringen nur Durcheinander.

    K.A. warums bei mir funzt und bei dir nicht.
    Dateien
    • GButton00.zip

      (12,35 kB, 95 mal heruntergeladen, zuletzt: )
    @ErfinderDesRades dein Projekt läuft bei mir auch. Also, nun stellt sich mir die Frage: Wie muss ich vorgehen, um eine eigenes Steuerelement erstellen zu können, welches später als .dll in anderen Projekten wieder verwendbar ist? Sprich, wie bist du vorgegangen als du das Testprojekt erstellt hast?

    Edit: Den Knopf will ich dann komplett selbst zeichnen, nur damit wir vom Gleichen sprechen.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

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

    ich hab deine Vorlage genommen, und userControl1 umbenannt.
    Anschließend die unnützen Sachen entfernt.
    Und dann noch ein Testprojekt zugefügt und zum Startprojekt gemacht.

    Wenn ich früher mal eine Bibliothek mit Winforms-Controls angelegt hab, so hab ich die als WinForms-Anwendung erzeugt, und dann den Projekttyp auf "Klassenbibliothek" umgestellt.
    So hatte ich alle für WinForms erforderlichen Verweise schoma drinne.
    Aber man kann sie auch händisch einbinden:
    WinForms, Drawing, evtl. Drawing2D, noch eventueller Drawning.Design oder so - wenn man auch eigene Designer entwickeln will.

    Für CustomControls ist die Attributierung System.ComponentModel.DesignerCategory("Code") wichtig, sonst geht da immer der dämliche Designer an, der zu garnix zu brauchen ist - ist ja kein UserControl.
    UserControl verwendet man dazu, um ein Steuerelement zu erstellen, das mehrere Steuerelemente gruppiert. Deshalb hat man auch einen Designer. Für die meisten Steuerelemente reicht daher das Erben von Control oder einem spezifischen Steuerelement. Ich halte das Erben von Button z.B. nicht für unangebracht, in diesem Fall.

    Eine Bibliothek von Steuerelementen sollte sich eigentlich einfach erzeugen lassen, indem man die Steuerelemente in einer Programmbibliothek hält und Verweise für System.Windows.Forms und System.Drawing hinzufügt und alle Steuerelemente in der Bibliothek ablegt; das ist zumindest auch meine Erfahrung und ich wüsste nicht, warum das nicht gehen sollte.

    Das mit den Mnemonics klappt jetzt? Das &-Zeichen heißt übrigens Et-Zeichen bzw. im Englischen ampersand.

    Viele Grüße
    ~blaze~

    ~blaze~ schrieb:

    Das mit den Mnemonics klappt jetzt?
    Leider nein, dass versuche ich ja durch das Erben von Button und der Verwendung dessen Text Property zu lösen. Eigentlich (so sehe ich das zumindest) ist das Erben hier gar nicht nötig, da alles andere sonst einwandfrei läuft. Sollte das die Lösung sein, hab ich da allerdings auch nichts dagegen...
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    mrMo schrieb:

    Sollte das die Lösung sein
    Was ist denn eigentlich Dein Ziel?
    Einen Deinen Button darzustellen?
    Was soll der können, was der "normale" nicht kann?
    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!
    @RodFromGermany

    Mein Ziel: Zeichnen mit GDI lernen.
    Der Weg dort hin: Ein Control (hier der Button) möglichst komplett selbst zeichnen.

    Was er (aktuell) kann:
    1.Verschiedene Farbverläufe beim Click und Hover (einstellbar).
    2. Zusätzlich nen Tooltip (hab den von Win genommen und zeichne drüber), Border- breite und Farbe sowie Font einstellbar.
    3. Und zu guter letzt kann das Ding auch als CheckButton (wieder eigener Farbverlauf einstellbar) genutzt werden (ähnlich der Checkbox). Hierzu hat der Button eine Eigenschaft namens "Button Style" wo man zwischen "normal" und "CheckButton" wechseln kann.

    Was er aktuell (noch) nicht kann:
    1. Die Mnemonics nutzen (Thema hier)
    2. Anderer Farbverlauf beim Focus (hatte ich vergessen, ist aber kein Problem und nicht Thema)

    Es geht hier nicht drum, dass der Standard WinForms Button nicht ausreicht, sondern das ich mir aktuell das Thema GDI anschaue, selbiges verstehen will um dieses dann sauber anwenden zu können wenn ich Bedarf habe. Ich kann ja nicht immer nur mit Datenbanken und Datenverarbeitung rum wurschteln, sondern muss meinen Horizont auch mal erweitern ;)
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Hier:

    C#-Quellcode

    1. [System.ComponentModel.DesignerCategory("Code")]
    2. public class GlossyButton : Button {
    3. public GlossyButton() {
    4. Paint += GlossyButton_Paint;
    5. }
    6. private void GlossyButton_Paint(object sender, PaintEventArgs e) {
    7. e.Graphics.FillEllipse(Brushes.Red, new Rectangle(0, 0, 50, 25));
    8. }
    9. }
    Beachte, dass meine ZeichenRoutine zusätzlich ist, also ich lass den Button erstmal sich selbst zeichnen, und das Event zeichnet nochmal ein Kringel drauf.
    Willst du wirklich alles selber zeichnen, mach so:

    C#-Quellcode

    1. [System.ComponentModel.DesignerCategory("Code")]
    2. public class GlossyButton : Button {
    3. protected override void OnPaint(PaintEventArgs e) {
    4. e.Graphics.FillEllipse(Brushes.Red, new Rectangle(0, 0, 50, 25));
    5. //base.OnPaint(e);
    6. RaisePaintEvent(this, e);
    7. }
    8. }
    Normal soll man base.OnPaint() aufrufen, um die Vererbungs-Kette zu erhalten. Aber wenn du wirklich alles selbst zeichnen willst, dann willst du die Vererbungskette ja unterbrechen, daher den Base-Aufruf unterlassen, aber immerhin stattdessen das Event trotzdem Raisen.

    Und wie gesagt: Das Mnemonic lass den Button doch machen, machter doch gut (wenn du ihn lässt).
    Dateien
    • GButton01.zip

      (12,52 kB, 84 mal heruntergeladen, zuletzt: )

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