Laden...

Variablen Werte von einer Clickmethode eines Buttons an eine andere Clickmethode übergeben

Letzter Beitrag vor 8 Monaten 11 Posts 548 Views
Variablen Werte von einer Clickmethode eines Buttons an eine andere Clickmethode übergeben

Ich bin ganz neu in der C#Welt und kenne mich noch nicht gut aus. Deshalb zerreist mich bitte nicht gleich, wenn ich etwas nicht gleich verstehe.

Aber nun zu meiner Frage:

XAML:
Ich habe einen Button platziert.

<Button x:Name="wuerfeln_btn" Content="Würfeln" Grid.Row="10" Grid.Column="4" Grid.ColumnSpan="2" FontSize="50" Click="Button_Click" />

Und ein Image:

<Image x:Name="wuerfel1_img" Grid.Row="5" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" MouseDown="wuerfel1_img_MouseDown"/>

Hier der Code vom Button:

private void Button_Click(object sender, RoutedEventArgs e)
{
    punkten_btn.Visibility = Visibility.Visible;
    passen_btn.Visibility = Visibility.Visible;
    wuerfeln_btn.Visibility = Visibility.Hidden;
    System.Media.SoundPlayer player = new System.Media.SoundPlayer(@"f:\wuerfelsound.wav");
    player.Play();

    int wuerfelanzanl = 6;
    Random zufallszahlen = new Random();
    int[] wuerfel = new int[wuerfelanzanl];
    for (int i = 0; i < wuerfel.Length; i++)
    {
        wuerfel[i] = zufallszahlen.Next(1, 7);
    }
    if (wuerfel[0] == 1)
    {
        wuerfel1_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 1.png"));
    }
    else if (wuerfel[0] == 2)
    {
        wuerfel1_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 2.png"));
    }
    else if (wuerfel[0] == 3)
    {
        wuerfel1_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 3.png"));
    }
    else if (wuerfel[0] == 4)
    {
        wuerfel1_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 4.png"));
    }
    else if (wuerfel[0] == 5)
    {
        wuerfel1_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 5.png"));
    }
    else
    {
        wuerfel1_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 6.png"));
    }
    
    for (int i = 0; i < wuerfel.Length; i++)
    {
        wuerfel[i] = zufallszahlen.Next(1, 7);
    }
    if (wuerfel[0] == 1)
    {
        wuerfel2_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 1.png"));
    }
    else if (wuerfel[0] == 2)
    {
        wuerfel2_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 2.png"));
    }
    else if (wuerfel[0] == 3)
    {
        wuerfel2_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 3.png"));
    }
    else if (wuerfel[0] == 4)
    {
        wuerfel2_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 4.png"));
    }
    else if (wuerfel[0] == 5)
    {
        wuerfel2_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 5.png"));
    }
    else
    {
        wuerfel2_img.Source = new BitmapImage(new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 6.png"));
    }
    usw.......

Hier überlege ich noch, wie ich den Code nicht 6 Mal schreiben muss, aber das Problem gehe ich später an.
Wie man erkennen kann sorgt ein Klick auf den Button dafür, dass 6 random-Zahlen erzeugt werden und in ein Array geschrieben werden.
Nun überprüfe ich mit For-Schleifen, welcher Wert im Index des Array vorhanden ist und lasse entsprechende Grafik anzeigen.

Und jetzt kommt mein Problem:
Nachdem gewürfelt wurde, möchte ich auf das entsprechende Bild klicken und mit dem Wert weiter rechnen.
Dafür habe ich diese Methode angelegt:

private void wuerfel1_img_MouseDown(object sender, MouseButtonEventArgs e)
{   
   
}

Doch ich weiß nicht, wie ich auf den Variablen-Wert, der von der ButtonClickMethode erstellt wurde, zugreifen kann.

Mir kam schon die Idee den Wert als in unsichtbare Labels zu schreiben, aber das scheint mir ein schlechter Stil zu sein. Das muss doch einfacher und anders gehen.

Ich hoffe Ihr versteht mich und könnt mir helfen......

Wenn Du dir einen Zustand merken willst, leg in der Klasse eine Variable an.
Die kannst Du dann in einer Methode setzen und in der anderen den Wert abrufen.

Und gegen Spagetthi Code:

wuerfel1_img.Source = new BitmapImage(new Uri($@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild {wuerfel[0]}.png"));

Oder Du baust ein Mapping:

var myMapping = new Dictionary<int, Uri>()
{
    [1] = new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 1.png"),
    [2] = new Uri(@"C:\Users\Marco\source\repos\Spielereien\Farkle\Ressources\img\wuerfelbild 2.png"),
    // ...
}

wuerfel1_img.Source = myMapping[wuerfel[0]];

Die for-Schleife sieht by the way aus, als sollte sie da nicht doppelt stehen.

Und Dateipfade so anzugeben ist eine blöde Idee, wie soll das denn auf einem anderen PC funktionieren?
WinForms kann Ressourcen verwalten, die Du dann direkt abrufen kannst, ohne dass Du irgendwo Dateien herum liegen hast.
Oder Du stellst in den Eigenschaften der Datei ein, dass sie ins Ziel-Verzeichnis kopiert wird, dann landet sie neben der exe und Du kannst sie mit einem relativen Pfad suchen.
Auf diese Weise sparst Du dir den hardcoded Pfad und dein Programm funktioniert auch auf einem anderen PC:

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Farkle
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }

        private void wuerfel1_img_MouseDown(object sender, MouseButtonEventArgs e)
        {   

        }
    }
}

An welcher Stelle müsste ich die Variable erstellen?

PS:
Mit Win Forms war das Ressourcenanlegen einfacher. Ich versuche das gerade mit WPF.

Sorry, aber wenn Du nicht weißt, wo/wie man Klassenvariablen nutzt, dann sind sowohl WinForms, als auch WPF zu hoch für dich.
Du solltest mit den Grundlagen anfangen und erst wenn die sitzen, machst Du mit komplexen Frameworks wie WinForms oder WPF weiter.

Klassenvariablen:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/fields

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

Das hilft mir nur leider nicht.

Klassen und so weiter verstehe ich, aber mein Problem ist, wie ich das in WPF anwende.
Wenn ich einfache Konsolenanwendungen schreibe verstehe ich das, aber ich weiß leider nicht, wo und an welcher Stelle GUI Programme was reingeschrieben haben wollen.

Das ist mein Problem.....

Wo darf ich eine eigene Klasse erstellen, damit sie berücksichtigt wird?
Mit einem Beispiel wäre mir mehr geholfen, als ein Hinweis, dass ich zu doof sei.
Ich lerne einfach besser, wenn man mir gezielt in meinem Code hilft.

WPF kann man prinzipiell genauso nutzen, wie Windows Forms, ist dann halt umständlicher und man legt sich selber Steine in den Weg. An deinem Code sollte das konzeptionell nur wenig ändern.
Wenn man es richtig machen will, dann nutzt man aber MVVM, darauf wurde WPF ausgelegt. [Artikel] MVVM und DataBinding

Und in dem verlinkten Artikel findest Du Beispiele.
Die Klassenvariable landet dann einfach in der Klasse, wo Du sie nutzen willst.

Aber wenn Du es in deinem Code sehen willst:

public partial class MainWindow : Window
{
    private int _zahl;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        _zahl++;
    }

    private void wuerfel1_img_MouseDown(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show(_zahl.ToString());
    }
}

Aber wie gesagt: Mit WPF arbeitet man eigentlich anders.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

Wenn man ganz neu ist, dann weiß man das leider alles nicht.
Man guckt zig Youtube Videos und liest hier und da und jeder macht es anders.

Die "Profis" machen leider keine Lernvideos und man macht einfach das nach, was andere machen.

Ich habe nur die Info:
Windows Forms nutzt man nicht mehr und ist veraltet.
Man nutzt jetzt WPF.
Ich nutze jetzt WPF weil die Elemente einfach mit skalieren, weil man mir Grid oder Pack oder was auch immer einfach Layouts erstellen kann.

Man guckt zig Youtube Videos und liest hier und da und jeder macht es anders.

Ich halte nichts von YouTube Videos ^^
Ich hab noch keine gute Video-Serie gesehen, die meisten sind entweder schlecht oder bleiben oberflächlich.

Aber es gibt ohne Ende andere Quellen im Internet.
Z.B. Microsoft bietet selber eine Tutorial-Reihe an.
Oder Du liest ein gutes Buch, ein kostenloses Buch wäre z.B. "Visual C# 2012", besser wäre aber der kostenpflichtige Nachfolger von 2019, weil sich dazwischen einiges geändert hat.

Es gibt auch hier einen Artikel zu dem Thema:
https://mycsharp.de/forum/threads/78856/faq-wie-finde-ich-den-einstieg-in-csharp

Windows Forms nutzt man nicht mehr und ist veraltet.
Man nutzt jetzt WPF.

Damit bist Du leider auch nicht mehr aktuell 😉

Ja, WinForms ist alt, sehr alt und wird nicht mehr weiterentwickelt.
Das gleiche gilt allerdings auch für WPF.

WPF verfolgt allerdings einen deutlich moderneren Ansatz, der damals Maßstäbe gesetzt hat, die man auch heute noch wiedererkennen kann.

Wenn Du nur eine einfache kleine Windows-Desktop-Anwendung entwickeln willst, ist WPF keine schlechte Wahl. Es ist alt, aber immer noch ausreichend und war damals gut durchdacht. Der Quasi-Nachfolger ist MAUI (basiert eigentlich auf Xamarin), allerdings hat das noch einige Macken, weshalb ich das ganz besonders einem Anfänger nicht empfehlen kann. Alternativ gibt's noch Community-Projekte wie Avalonia, das noch aktiv gepflegt wird, auf mich aber nicht so gut durchdacht wirkt.

Die Zukunft geht aber eher in Richtung Blazor und Web im allgemeinen.
MAUI kann ein Blazor-Frontend darstellen, so hast Du die Möglichkeit, den riesigen Umfang an Frameworks aus dem Web in einer Desktop-App zu nutzen. Mit Blazor funktioniert MAUI dann auch ausreichend gut. Alternativ kenne ich noch Electron und Photino.NET, Letzteres wirkt noch halb fertig, funktioniert aber schon jetzt sehr gut und ist sehr leichtgewichtig
Das alles macht Blazor sehr interessant, da man mit dem Web eine Frontend-Basis hat, die jeder mehr oder weniger versteht und die überall funktioniert, man muss also nicht das ganze Frontend doppelt und dreifach bauen, nur weil man mehrere Ziel-Geräte unterstützen will.
Ob das für dich ein relevantes Argument ist, musst Du dir aber selbst überlegen.

WPF hat damals Maßstäbe gesetzt, aber einen wirklich würdigen Nachfolger gibt es leider noch nicht.
Also ist WPF nicht pauschal falsch und zum Lernen auch deutlich einfacher, als die Alternativen.
Aber wenn Du "man nutzt jetzt WPF" schreibst, ist das leider falsch, "man" (also generell) nutzt es heute nicht mehr, außer man hat gute Gründe.
Die Zukunft liegt eher bei Web-Dechnologien und bei .NET heißt das aktuell Blazor.

Ob Du nun mit WPF lernen, oder nochmal umsatteln solltest, kann ich dir nicht sagen.
Blazor arbeitet mit ASP.NET Core und die Einstiegshürde ist vermutlich um einiges größer (dafür gibt's aber sehr gute Artikel von Microsoft), allerdings ist dieser Technologie-Stack dafür auch um einiges sicherer und der geradlinigere Ansatz für die Kommunikation von der UI mit dem "Code Behind" ist mit Blazor leichter zu verstehen, als MVVM mit WPF.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

Ah okay.
Das sind wieder ganz neue Dinge, die ich vorher noch nicht gesagt bekommen oder gelesen habe.
Der Grund, warum ich mir C# ansehe ist, dass mein Sohn gerne mal mit Unity ein Spiel erstellen will und das basiert ja auf C#.
Persönlich kenne ich auch immer nur die Grundlagen von Python und C#.
Lua hatte ich mir auch mal angesehen, weil ich Handyanwendungen erstellen wollte, aber das basieren die ganzen Videos auch immer nur auf Konsolenanwendungen.
Das macht zum lernen auch Sinn, aber wenn es dann um GUI geht, dann sind gute Videos spärlich.
Vieles funktionierte auch nicht, wie im Video angegeben, also habe ich das auch wieder verworfen.

In Python habe ich mit Tkinter ein paar einfache Programme geschrieben. Unter Linux konnte ich das sogar zu einer apk umwandeln.
Aber das war auch alles umständlich.

Mit Pygame habe ich auch kleinere 2D Spiele erstellt, aber das ist auch aufwendiger, als mit modernen Engines.
Also hieß es jetzt:
Unity und C#.

Ich habe nie mit Unity gearbeitet, aber nach dem, was ich gesehen/gehört habe, könnten Unity und gängige UI-Frameworks kaum weiter voneinander entfernt sein.

Wenn dein Ziel also nur ist, mit Unity helfen zu können, warum lernst Du dann nicht Unity?
Aber zum Lernen der Sprach-Grundlagen ist WPF ganz gut geeignet, es ist nicht zu komplex, zwingt aber zur Verwendung von fortgeschrittenen Dingen.
Anfangen solltest aber auch Du mit der Konsole, die Frage, wo eine Klassenvariable hin muss, darfst Du bei WPF nicht stellen müssen, das muss alles fest sitzen.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

Ich möchte einfach in alles mögliche reinschauen, was mit C# so möglich ist.
Eigentlich wollte ich auch nur einen BMI Rechner und einen Würfelgenerator usw bauen.
Das hat auch mit Windows Form und WPF gut geklappt.
Mit Konsolenanwendungen habe ich auch angefangen, aber wollte jetzt mal etwas grafisches machen.
Und da weiß ich wie gesagt immer nicht, wo das Programm was verlangt.
Jetzt hast du mir einmal konkret den Tip gegeben und jetzt weiß ich es. So lerne ich persönlich immer besser, wenn man mir direkt Code gibt für mein Problem.
Dann speichere ich das ab, wie das ging und es geht weiter.
Deswegen helfen mir auch so allgemeine Code antworten nicht so gut. Die sind oft nicht so, wie ich es genau brauche.
Konsolenanwendungen habe ich auch ein paar kleinere gemacht.
Tic Tac Toe, Zahlenratespiel und so einzelne allgemeine Dinge.
Daten aus einer Datei laden, bzw. schreiben.
Klassen anlegen und Methodenschreiben.

Aber wie gesagt: Dieses wissen dann in der GUI anwenden ist nochmal anders, weil man da auch mit Eventhandlern arbeitet.
Auch hat man in der Konsole keine Textboxen oder Labels, die man ansprechen muss.
Oder Grafiken einblenden.
Buttons mit Funktionen bestücken. Eventuell auch mal Buttons verstecken oder deaktivieren, wenn eine Checkbox nicht aktiviert ist.
All das lernt man in der Konsole nicht.

Mir macht das Programmieren als Hobby auch echt Spaß.
Die ersten versuche hatte ich mit C während meiner Ausbildung als Industrieelektroniker anfang der 2000'er.

Tja.....und jetzt ist der Sohn bald 12 und findet Programmieren auch toll. Und jetzt fange ich halt mal mit C# an.
Mein Code ist für Profis wahrscheinlich grausig, aber das liegt auch einfach daran, dass man viele Funktionen und Eigenschaften gar nicht kennt.
Und dann macht es noch jeder anders.

Alles nicht so einfach, aber ich bleib dran.