GUI updatet nur, wenn Taste oder Button 2× gedrückt wird.

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

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    GUI updatet nur, wenn Taste oder Button 2× gedrückt wird.

    Hallo,

    ich habe vorhin Tasten genutzt, die bestimme Variablen ändern, zum Beispiel so im KeyDown-Handler:

    C#-Quellcode

    1. if (e.KeyCode == Keys.U)
    2. {
    3. B_3D.TurnCamera(1.0, 0.0, 0.0);
    4. LetCalculateAndDrawAndDisplay();
    5. return;
    6. }

    Und das für alle möglichen Richtungen und Winkel.


    Es gibt eine Methode, die etwas asynchron berechnet:

    C#-Quellcode

    1. private async void LetCalculateAndDrawAndDisplay()
    2. {
    3. await Task.Run(() => B_3D.Draw(PictureBox1.Size.Width, PictureBox1.Size.Height));
    4. }


    Wenn die Methode fertig ist, soll die GUI geupdatet werden.
    Beispiel: Ich drücke U, das den X-WInkel um 1 erhöht. Dann drücke ich I, das den X-Winkel um 1 erniedrigt. Also jetzt erwarte ich, dass alles so wie vorher ist. Leider muss ich 2×, teilweise 3×, I drücken, weil sich die GUI nicht updatet. Ich habe dann natürlich zu viel erniedrigt. Die Berechnung stimmt; das habe ich geprüft. Ich nutze mittlerweile ein Event, welches feuert, wenn in Draw der letzte Schritt fertiggestellt ist. Leider ohne Erfolg.
    Ich hatte schon probiert, die Berechnung nicht asynchron laufen zu lassen. Oder CamDir shared zu machen. Mit Buttons hab ich's auch probiert.

    C#-Quellcode

    1. private void On_GUI_Update_required(object sender, EventArgs e)
    2. {
    3. this.Invoke((Action)(() => Update_GUI()
    4. ));
    5. }
    6. private void Update_GUI()
    7. {
    8. PictureBox1.Image = null;
    9. PictureBox1.Image = B_3D_Engine.displayedBitmap;
    10. Label_Kamera_x.Text = Math.Round(B_3D.CameraPos.x, 0).ToString(Deu);
    11. Label_Kamera_y.Text = Math.Round(B_3D.CameraPos.y, 0).ToString(Deu);
    12. Label_Kamera_z.Text = Math.Round(B_3D.CameraPos.z, 0).ToString(Deu);
    13. Label_Obj_x.Text = Math.Round(B_3D.cu.x_angle, 0).ToString(Deu);
    14. Label_Obj_y.Text = Math.Round(B_3D.cu.y_angle, 0).ToString(Deu);
    15. Label_Obj_z.Text = Math.Round(B_3D.cu.z_angle, 0).ToString(Deu);
    16. Label_look_at.Text = $"{Math.Round(B_3D.CamDir.x, 2).ToString(Deu)} | {Math.Round(B_3D.CamDir.y, 2).ToString(Deu)} | {Math.Round(B_3D.CamDir.z, 2).ToString(Deu)}";
    17. }


    Die Berechnung inkl. GUI-Update dauert 293 Millisekunden. Ich kann nicht zu schnell geklickt haben.

    Die anderen Werte werden brav geupdatet.

    CamDir ist in der Instanz B_3D ein Vektor. Allerdings ist das bei mir eine separate Klasse.

    C#-Quellcode

    1. public sealed class SimpleVector
    2. {
    3. public double x, y, z;
    4. public SimpleVector(double x, double y, double z)
    5. {
    6. this.x = x;
    7. this.y = y;
    8. this.z = z;
    9. }
    10. }


    CamDir wird bei jedem Aufruf von Draw() neu berechnet
    CamDir = new SimpleVector(...

    Edit: Ich habe gerade festgestellt, CamDir wird doch nicht richtig neu beschrieben... :(

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

    Bartosz schrieb:

    Es gibt eine Methode, die etwas asynchron berechnet:
    Wenn der Name der Prozedur korrekt ist, zeichnet diese Methode asynchron, indem sie invokt.
    Das sollte synchron laufen.
    Irgendwo musst Du dann ein x.Invalidate() aufrufen, damit die Form / das Control neu gezeichnet wird.
    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!