Grafikprogrammierung / Problem mit dem Auslesen der Größe nach Formulargrößenänderung

  • C#

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von MajorOli.

    Grafikprogrammierung / Problem mit dem Auslesen der Größe nach Formulargrößenänderung

    Hallo zusammen und einen schönen guten Abend,

    Ich erstelle gerade zur Übung ein kleines Spiel (Pong). Das Programm läuft soweit. Ich möchte jetzt über ein Menü, was in einer anderen Form geladen wird, das Spielfeld anpassen.
    Die Anpassung des Spielfeldes funktioniert auch.


    Mein Problem:
    Wenn ich das Spielfeld angepasst haben und ich erneut das Spielfeld ändern möchte dann soll die zuvor ausgewählte Option markiert werden.
    Das bekomme ich Aktuell nicht hin.

    Mein Ansatz:
    Ich hatte mir gedacht ich hole mir durch eine Methode einfach die Aktuelle Breite und vergleiche diese.
    Leider wird nach der Neuzeichnung des Formulares (Form1) die Aktuelle Breite nicht aktualisiert. Dieses Problem verstehe ich aktuell nicht.

    Code und Problembeispiel
    Im folgenden Code wird aus dem zweiten Formular (EinstellungenDialog) der ausgewählte Wert geholt und dann die Breite und die Höhe gesetzt und neu gezeichnet.
    Spoiler anzeigen

    C#-Quellcode

    1. private void spielfeldToolStripMenuItem_Click(object sender, EventArgs e)
    2. {
    3. Point neueGroesse = new Point(0, 0);
    4. EinstellungenDialog neueWerte = new EinstellungenDialog();
    5. //wenn der Dialog über die "OK"-Schaltfläche beendet wird
    6. if (neueWerte.ShowDialog() == DialogResult.OK)
    7. {
    8. //die neue Größe holen
    9. neueGroesse = neueWerte.LiefereWert();
    10. //den Dialog wieder schließen
    11. neueWerte.Close();
    12. //das Formular ändern
    13. this.Width = neueGroesse.X;
    14. this.Height = neueGroesse.Y;
    15. //neu ausrichten
    16. this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
    17. this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
    18. //die Zeichenfläche neu beschaffen
    19. zeichenflaeche = spielfeld.CreateGraphics();
    20. //das Spielfeld neu setzen
    21. SetzeSpielfeld();
    22. //Spielfeld löschen
    23. zeichenflaeche.Clear(spielfeld.BackColor);
    24. //und einen neuen Ball und einen neuen Schläger zeichnen
    25. NeuerBall();
    26. }
    27. }


    Die Methode aus dem zweiten Formular sieht wie folgt aus
    Spoiler anzeigen

    C#-Quellcode

    1. //die Methode liefert den ausgewählten Wert
    2. public Point LiefereWert()
    3. {
    4. Point rueckgabe = new Point(0, 0);
    5. if (radioButton320.Checked == true)
    6. rueckgabe = new Point(320, 200);
    7. if (radioButton640.Checked == true)
    8. rueckgabe = new Point(640, 480);
    9. if (radioButton1024.Checked == true)
    10. rueckgabe = new Point(1024, 768);
    11. if (radioButtonMaximal.Checked == true)
    12. rueckgabe = new Point(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
    13. return rueckgabe;
    14. }


    Beim ersten Durchlauf funktioniert alles Problemlos und die Einstellung wird korrekt gesetzt.
    Beim zweiten Durchlauf allerdings bleibt der Wert über

    C#-Quellcode

    1. this.width
    unverändert obwohl das Formular eine andere größe hat.

    1.Durchlauf OK


    2. Durchlauf mit 1024x768 Pixel ohne Änderung der Breite. Auch Size.width hat keine Besserung ergeben


    Vielleicht hat jemand eine Idee woran das liegen kann.

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

    ich kann am 2. Bild kein Fehler feststellen: Das Überwachungsfenster zeigt 640 als Width an, und das ist auch der Wert, den GetSpielfeldWidth() returnt.
    Nach diesem Bild tuts halt dein Dialog nicht, oder die Auswertung dessen Ergebnisses.
    Interessanter wäre also ein Haltepunkt in Listing#1, Zeile#17, ob tatsächlich der erwünschte Wert zugewiesen wird, und wie zum Donner es zugeht, dass das Form diesen Wert dennoch nicht annimmt.
    Das mit dem vergrößern passt. Aber wenn ich dann erneut die Einstellung ändern möchte, soll der Radiobutton aktive sein der zur aktuellen Spielfeldgröße passt.
    Aktuell funktioniert das nicht.

    Bei einer Spielfeldgröße von 1024x768 liegt die Option immer bei 640x480 obwohl er bei 1024x768 checked sein müsste
    Im folgenden Beispiel müsste die Option 1024.768 gesetzt sein statt 640x480. Das geschieht dadurch das der Rückgabewert this.Width sich nicht ändert.
    Und da liegt mein Problem. Wie kann ich quasi die passende Option an die Aktuelle Spielfeldgröße setzen.
    ehm... wie erklär ich das am besten.....

    Das 2te Formular soll wissen wie groß das erste Formular ist und dann soll die passende Option dazu ausgewählt werden.
    Das 2te Formular soll also bei Aufruf den aktuellen IST Zustand anzeigen. Aber das macht es ja nicht da er als Vergleichswert die falsche Breite zurückgeliefert bekommt (Immer 640x480) und das ist ja falsch
    da sich ja die Größe ändert.

    Ich bin kein so guter Erklärbär. Deshalb dachte ich das Bilder da eventuell mehr helfen.

    ErfinderDesRades schrieb:

    jetzt verstehe ich so, dass Form2 sich die Breite von Form1 zu holen versucht - und dabei läuft was schief (kann mir auch denken, was, wenns das ist).
    Jdfs das wäre schon vom Ansatz falsch.
    Daher Frage: Ist dem so?
    Wenn dem so ist - gibts vlt relevanten Code dazu?

    Ja genau das ist das Problem.

    Relevanter Quelltext ist im Anfangspost.
    Dann gibt es noch eine "Paint_Methode" Könnte die das übel Sein? Sonst habe ich hier knapp 500 Zeilen Quelltext.....
    Was wären denn relevanter Code? Alles was zeichnet?

    C#-Quellcode

    1. private void spielfeld_Paint(object sender, PaintEventArgs e)
    2. {
    3. ZeichneSpielfeld();
    4. ZeichneZeit(Convert.ToString(aktuelleSpielzeit));
    5. }
    Aso, der Code im 2ten Formular schaut wie folgt aus

    C#-Quellcode

    1. private void EinstellungenDialog_Load(object sender, EventArgs e)
    2. {
    3. Form1 Werte = new Form1();
    4. int FeldGroesse = Werte.GetSpielfeldGroesse();
    5. if (FeldGroesse == 320)
    6. radioButton320.Checked = true;
    7. if (FeldGroesse == 640)
    8. radioButton640.Checked = true;
    9. if (FeldGroesse == 1024)
    10. radioButton1024.Checked = true;
    11. if (FeldGroesse > 1024)
    12. radioButtonMaximal.Checked = true;
    13. }


    und die Methode GetSpielfeldGroesse() im Formular 1 ist dann

    C#-Quellcode

    1. public int GetSpielfeldGroesse()
    2. {
    3. return this.Width;
    4. }
    Jepp - das war genau der falsch Ansatz, den ich seit post#8 vermutete. Nur formulierst du falsch, wenn du sagst

    MajorOli schrieb:

    Die Steuerung erfolgte NICHT im 2ten Formular sondern musste durch das Hauptformular erfolgen.
    Sie erfolgte ja DOCH im 2ten Formular - und das ist eben Grütze.



    Lass mich deine Aufmerksamkeit noch auf ein kleines OOP-Schlüsselwort lenken, auf new

    MajorOli schrieb:

    C#-Quellcode

    1. Form1 Werte = new Form1();
    Das tut was es sagt (Nomen est Omen!) - es erzeugt ein new - neues Form1.
    Ein neues - also es ist nicht das Form, was bereits zu sehen ist auffm Bildschirm - nein: new!
    Und dieses neue Form ist tatsächlich nirgends zu sehen - es ist ja nirgends Werte.Show(); aufgerufen worden.
    Jo, und von diesem neuen, unsichtbaren Form1 rufst du die Width ab- die ist im jungfräulichen Zustand offsichtlich immer 640.

    Also wisse, was die Schlüsselworte bedeuten, dann weisst du (eher) was du tust, und programmieren kann dann auf einmal einem vollkommen logisch vorkommen ;) .



    Übrigens auch wenns jetzt funktioniert würde ich dennoch dein Code kurz überarbeiten, weil du noch immer falsche Datentypen und Kontrollstrukturen verwendest - Stischwort Size statt Point, und elseif-Kette.
    Aber dafür braüchte ich den aktuell funkttionierenden relevanten Code.
    Relevant ist, wie Form2 geöffnet wird, und wie dort die Radiobutton voreingestellt werden.
    Und weiters, wie nach Schliessen des Dialogs, die User-Eingaben dann ausgewertet werden, um die Form1-Size neu festzulegen.

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

    ErfinderDesRades schrieb:

    Jepp - das war genau der falsch Ansatz, den ich seit post#8 vermutete. Nur formulierst du falsch, wenn du sagst

    MajorOli schrieb:

    Die Steuerung erfolgte NICHT im 2ten Formular sondern musste durch das Hauptformular erfolgen.
    Sie erfolgte ja DOCH im 2ten Formular - und das ist eben Grütze.

    Jepp genau diese "Grütze" hat mich lange beschäftigt...

    ErfinderDesRades schrieb:


    Das tut was es sagt (Nomen est Omen!) - es erzeugt ein new - neues Form1.Ein neues - also es ist nicht das Form, was bereits zu sehen ist auffm Bildschirm - nein: new!Und dieses neue Form ist tatsächlich nirgends zu sehen - es ist ja nirgends Werte.Show(); aufgerufen worden.Jo, und von diesem neuen, unsichtbaren Form1 rufst du die Width ab- die ist im jungfräulichen Zustand offsichtlich immer 640.Also wisse, was die Schlüsselworte bedeuten, dann weisst du (eher) was du tust, und programmieren kann dann auf einmal einem vollkommen logisch vorkommen

    Jepp das ist absolut korrekt! Da war auch mein Denkfehler. Die Anweisung mit dem neuen Formular im 2ten Code ist absolut falsch gewesen.


    In Form1 heißt es:

    C#-Quellcode

    1. EinstellungenDialog neueWerte = new EinstellungenDialog();

    und dann muss nur noch die Aktuelle Breite an eine Methode an Form2 übergeben werden.
    Diese lautetet dann:

    C#-Quellcode

    1. //Die Aktuelle größe übergeben
    2. neueWerte.setOption(this.Width);


    Die Methode im 2ten Formular setzt dann nur noch den richtigen Optionsbutton:

    C#-Quellcode

    1. public void setOption(int Breite)
    2. {
    3. if (Breite == 320)
    4. radioButton320.Checked = true;
    5. if (Breite == 640)
    6. radioButton640.Checked = true;
    7. if (Breite == 1024)
    8. radioButton1024.Checked = true;
    9. if (Breite > 1024)
    10. radioButtonMaximal.Checked = true;
    11. }


    Danach wird ja auch erst der Showdialog aufgerufen:

    C#-Quellcode

    1. //wenn der Dialog über die "OK"-Schaltfläche beendet wird
    2. if (neueWerte.ShowDialog() == DialogResult.OK)


    Der Komplette Quelltext ist dann wie folgt:
    @ErfinderDesRades der Aufruf erfolgt über den Showdialog in Zeile 9. Die Radiobutton haben keine Voreinstellungen. Der erste der gesetzt wurde ist der aktive.
    Über den Showdialog werden die Usereingaben direkt ausgewertet und verarbeitet. Die Mehtode neueWerte.LiefereWert() gibt die ausgewählte Breite und Höhe zurück.
    Spoiler anzeigen

    In Form1:

    C#-Quellcode

    1. private void spielfeldToolStripMenuItem_Click(object sender, EventArgs e)
    2. {
    3. Point neueGroesse = new Point(0, 0);
    4. EinstellungenDialog neueWerte = new EinstellungenDialog();
    5. //Die Aktuelle größe übergeben
    6. neueWerte.setOption(this.Width);
    7. //wenn der Dialog über die "OK"-Schaltfläche beendet wird
    8. if (neueWerte.ShowDialog() == DialogResult.OK)
    9. {
    10. //die neue Größe holen
    11. neueGroesse = neueWerte.LiefereWert();
    12. //den Dialog wieder schließen
    13. neueWerte.Close();
    14. //das Formular ändern
    15. this.Width = neueGroesse.X;
    16. this.Height = neueGroesse.Y;
    17. //neu ausrichten
    18. this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
    19. this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
    20. //die Zeichenfläche neu beschaffen
    21. zeichenflaeche = spielfeld.CreateGraphics();
    22. //das Spielfeld neu setzen
    23. SetzeSpielfeld();
    24. //Spielfeld löschen
    25. zeichenflaeche.Clear(spielfeld.BackColor);
    26. //und einen neuen Ball und einen neuen Schläger zeichnen
    27. NeuerBall();
    28. }​


    In Form2 (was dann aufgerufen wird):

    C#-Quellcode

    1. public Point LiefereWert()
    2. {
    3. Point rueckgabe = new Point(0, 0);
    4. if (radioButton320.Checked == true)
    5. rueckgabe = new Point(320, 200);
    6. if (radioButton640.Checked == true)
    7. rueckgabe = new Point(640, 480);
    8. if (radioButton1024.Checked == true)
    9. rueckgabe = new Point(1024, 768);
    10. if (radioButtonMaximal.Checked == true)
    11. rueckgabe = new Point(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
    12. return rueckgabe;
    13. }
    14. public void setOption(int Breite)
    15. {
    16. if (Breite == 320)
    17. radioButton320.Checked = true;
    18. if (Breite == 640)
    19. radioButton640.Checked = true;
    20. if (Breite == 1024)
    21. radioButton1024.Checked = true;
    22. if (Breite > 1024)
    23. radioButtonMaximal.Checked = true;
    24. }



    Logisch oder? :D
    Hier meine Verhübschung:

    C#-Quellcode

    1. class Form2 {
    2. public Size LiefereWert() {
    3. if (radioButton320.Checked) return new Size(320, 200);
    4. if (radioButton640.Checked) return new Size(640, 480);
    5. if (radioButton1024.Checked) return new Size(1024, 768);
    6. if (radioButtonMaximal.Checked) return new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
    7. }
    8. public void setOption(int Breite) {
    9. if (Breite <= 320) radioButton320.Checked = true;
    10. else if (Breite <= 640) radioButton640.Checked = true;
    11. else if (Breite <= 1024) radioButton1024.Checked = true;
    12. else radioButtonMaximal.Checked = true;
    13. }
    14. }
    15. class Form1 {
    16. private void spielfeldToolStripMenuItem_Click(object sender, EventArgs e) {
    17. using (var neueWerte = new EinstellungenDialog()) {
    18. //Die Aktuelle größe übergeben
    19. neueWerte.setOption(this.Width);
    20. //wenn der Dialog über die "OK"-Schaltfläche beendet wird
    21. if (neueWerte.ShowDialog() != DialogResult.OK) return;
    22. //die neue Größe holen und das Formular ändern
    23. this.Size = neueWerte.LiefereWert();
    24. //neu ausrichten
    25. this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
    26. this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
    27. //die Zeichenfläche neu beschaffen
    28. zeichenflaeche = spielfeld.CreateGraphics();
    29. //das Spielfeld neu setzen
    30. SetzeSpielfeld();
    31. //Spielfeld löschen
    32. zeichenflaeche.Clear(spielfeld.BackColor);
    33. //und einen neuen Ball und einen neuen Schläger zeichnen
    34. NeuerBall();
    35. }
    36. }
    37. }
    Beachte (die Abwesenheit eines Spoilers), den direkten return statt unnützer weiterer If-bedingungen, die Abschaffung des unnützen Vergleichs mit True, den Using-Block, die else if - Kette, die Verwendung von Size statt Point.
    Was dir nicht unmittelbar einleuchtet, das recherchiere nach - ist alles wichtig.
    Oder fragen.
    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.