Laden...

Wie kann ich Klassen voneinander abgrenzen?

Erstellt von Skydanith vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.149 Views
S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren
Wie kann ich Klassen voneinander abgrenzen?

Ahoi,

habe gestern mit Programmieren angefangen. Ich wollte jetzt mal so eine Art Quiz programmieren.
Sobald eine Frage abgeschlossen ist, beginnt offenbar der Anweisungsblock von vorne und deshalb taucht die MessageBox Text von der letzten Frage auf - w

as natürlich falsch ist.

Ich habe das Gefühl dass ich für jede Frage eine neue Klasse erstellen muss. Füge ich aber eine Klasse hinzu und kopiere die Frage 2 hinein, ist sämtlicher Code rot unterstrichelt. VS bemängelt, dass die Klasse keinen Bezug hat.

Meine Vermutung ist, dass ich einen klareren Cut brauche von einer Frage zur anderen. Die Frage ist, wie stelle ich dass am besten an?

Hier ist mal der Code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace E_Learning
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {


            lblPunkte.Text = "";

            //Frage eins/////////////////

            if (radioFrage1.Checked)
            {
                MessageBox.Show("Die Antwort ist leider falsch!");
            }
            else if (radioFrage2.Checked)
            {
                MessageBox.Show("Das ist richtig!");
                lblPunkte.Text += 100;
            }
            // Frage zwei/////////////////////////////////////
            {


                lblFrage.Text = ("Wer ist der Brandschutzleiter?");
                radioFrage1.Text = ("Herr xxxxx2");
                radioFrage2.Text = ("Herr xxxxx1");
                radioFrage1.Checked = false;
                radioFrage2.Checked = false;
            }
            if (radioFrage1.Checked)
            {
                MessageBox.Show("Richtig!");
                lblPunkte.Text += 200;
            }
            else if (radioFrage2.Checked)
            {
                MessageBox.Show("Leider nein ...");
            }
            {
            }
        }
            }
}

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo Skydanith,

cool, dass du mit dem programmieren begonnen hast 😃

Du kannst dir mal [FAQ] Wie finde ich den Einstieg in C#? anschauen, dort findest du Antworten auf deine Fragen.

Auch [Artikel] C#: Richtlinien für die Namensvergabe

Zu deinem Problem: Es wäre ja Ratsam wenn man eine Art Container hätte für eine Frage, den man immer wieder unterschiedlich befüllen könnte. Die Antwort gibts dann dazu.

Stell dir vor du machst dir ein Objekt "Question" mit den Infos, die du brauchst. Dann eine Liste, in der du dir alle Fragen hältst, dann brauchst du nur noch rausfinden was für eine Frage angeklickt wurde, die Antwort vergleichen und evtl die Punkte berechnen.

Schau, dass deine Klassen "nebeneinander" liegen. (einfach schnell heruntergetippt). Die Klammern helfen dir auch sehr zu sehen wo dein Code hin muss.

    class Program
    {
        static void Main(string[] args)
        {
            Question question1 = new Question("Frage", "Antwort");
        }
    }

    class Question
    {
        public string Text { get; private set; }
        public string Answer { get; private set; }

        public Question(string text, string answer)
        {
            Text = text;
            Answer = answer;
        }
    }

Ich finde das Ziel sehr ambitioniert aber absolut machbar. Bevor du aber startest: Schau dir die Grundlagen an und dann wird einiges klarer.

Gruss

Coffeebean

S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren

Bin zwar noch newb, aber ich denke du willst vorschlagen 2 Container zu machen. Der eine erhält die Fragen. Der andere Die Antworten.
Mit der Syntax get und set, kann man wohl anschließend bequem per button Fragen hinzufügen oder löschen. Nennt sich ja Getter und Setter oder?
Mit "Klassen" nebeneinander legen, meinst du wohl diesen Klassenmanager? Die Schwierigkeit liegt in der Umsetzung. Da fehlt mir einfach noch das Handwerk, obwohl mich das erst recht anspornt das Problem zu lösen.
Ich nehme mal an, jeder Container wird dann eine "Klasse" sein.
D.h. ich brauche 2 Klassen neben der Mainmethode und diese müssen auch miteinander verbunden werden.
Fragen über Fragen.

Danke jedenfalls für den Link. Auch wenn ich gar nicht so recht weis, wo ich überhaupt anfangen soll.

Gruß

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo Skydanith,

nenenene...aber wie gesagt: Lies dir mal die Grundlagen von OOP durch. Also, natürlich kann das deine gewählte Lösung sein. Aber bei zwei Listen mit Fragen auf der einen und Antworten auf der anderen musst du ja immernoch wissen, welche Antwort zu welche Frage gehört. 😉 Eventuell der Index? Aber machs dir nicht schwieriger als es ist.

Lies dir die Grundlagen von OOP und C# durch, dann wird vieles klarer.

Gruss

Coffeebean

5.658 Beiträge seit 2006
vor 6 Jahren

Hi Skydanith,

Da fehlt mir einfach noch das Handwerk, obwohl mich das erst recht anspornt das Problem zu lösen.

Lies dir die von Coffeebean geposteten Links durch, schau mal in ein C#-Buch (z.B. 🛈 ) rein, und beschäftige dich mit Objektorientierter Programmierung. Dann beantworten sich die meisten Fragen von ganz allein.

Weeks of programming can save you hours of planning

S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren

Ich sauge gerade C#6 mit Visual Studio 2015 förmlich in mich auf. Ich wurde doch noch warm mit dem Buch. Man muss etwas mehr denken wie beim letzten Buch, aber das hilft die Zusammenhänge besser zu verstehen und nachzuvollziehen.

Der vorgeschlagene Quellcode wird allmählich klarer und ich verstehe den Zusammenhang.

Ich hätte nie gedacht dass man so süchtig nach Wissen werden kann.

Danke an alle nochmal. Ja, man merkt, dass ich gerade auf einem Höhenflug bin 😄

S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren

Moin,

hab jetzt an der Stelle mal weiter rumhantiert. Danke nochmal an Coffeebean. Du hast mich in die richtige Richtung geschubst. Dein Beispiel war zwar für eine Konsolenanwendung, aber ich habe nun versucht, dass ganze in einer Windows Forms Anwendung unterzukriegen.

Ich sag jetzt erstmal meine bisherigen Gedankengänge.

Es ging darum Frage Objekte zu erstellen und diesen mit einem Antworten Pool zu verbinden.
Mein vielversprechendster weg war, die Objekte in Arrays abfragen zu lassen.
Dabei habe ich sogar gelernt, dass man einen bool Aarray erstellen kann. Anschließend kam ich auf die glorreiche Idee, die Checkboxen mit einem bool Indizies zu verbinden.
Dummerweise meckert aber später, sobald ich einen String Array mit einem bool Array kombinieren will. Trotz allen. Der Lerneffekt und die praktische Übung mit Arrays und mehr dimensionalen Arrays war groß.
Ihr ahnt es aber, die anfängliche Euphorie verfolg schnell.

Ich hatte mittlerweile sehr viele Lösungsansätze herausgefunden. Einige funktionierten, andere nicht. Letztendlich scheiterte es immer an einer Stelle.

Die Anwendung startet mit der ersten Frage. klicke ich auf den Button, prüft er das Ergebnis und geht zur nächsten Frage. Allerdings prüft er dann schon bereits die zweite Frage, obwohl der User noch gar nix anklicken konnte.
Kurz gesagt, er rattert alle Ergebnisse runter. Es soll aber ein break Point zwischen jeder sein.

Seit fast 2 Tagen sitze ich an diesen Problem und tüftle mit Arrays und Objekten rum. Dabei habe ich viel gelernt. Auf die Lösung dieses Problems bin ich allerdings noch nicht gestoßen.
Das perverse ist, dass ich bin noch immer motiviert. 😃

Hab schon überlegt ob ich seperate Fenster erstelle für jede Frage. Das könnte ich tun. Allerdings ich will es so haben und nicht anders.

Ich will per Button klick eine Prüfung der Antwort und dass er automtatisch zur nächsten Frage geht, aber auf die Reaktion des Users wartet.

Ich habe die Befürchtung, dass das Problem eigentlich sehr simpel sein wird.

Hier ist mal der Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {

        Question frageEins = new Question("Wie ist dein Name?");
        Question frageZwei = new Question("Wie ist dein Vorname?");
        

        string[] arFraAnt = new string[10];
        bool[] checkboxen = new bool[10];

        public Form1()
        {
            InitializeComponent();
        }

        public void Form1_Load(object sender, EventArgs e)
        {
                

            label1.Text = "Wie heißt mein Hund";
            radioButton1.Text = "aaaaa";
            radioButton2.Text = "bbbbbbb";
            radioButton3.Text = "cccccccc";
            radioButton4.Text = "dddddddd";

            arFraAnt[0, 0] = frageEins.Frage;
            arFraAnt[1, 0] = frageZwei.Frage;
       

            checkboxen[0] = radioButton1.Checked;
            checkboxen[1] = radioButton2.Checked;
            checkboxen[2] = radioButton3.Checked;
            checkboxen[3] = radioButton4.Checked;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (string s in arFraAnt)
                label1.Text = arFraAnt[5];

            { 
                if (radioButton1.Checked)
                {
                    MessageBox.Show("Das ist richtig!");
                 
                }
                else if (radioButton2.Checked || radioButton3.Checked || radioButton4.Checked)
                MessageBox.Show("Das ist falsch!");
                

            }

            label1.Text = frageEins.Frage;
            radioButton1.Text = "Fa. hans";
            radioButton2.Text = "Fa. franz";
            radioButton3.Text = "Fa. tanz";
            radioButton4.Text = "Fa. manz";

            if (checkboxen[3])
            {
                MessageBox.Show("Das ist richtig!");
            }
            else if (radioButton1.Checked || radioButton2.Checked || !radioButton3.Checked || radioButton4.Checked)
                MessageBox.Show("Das ist falsch!");
            radioButton3.Checked = false;



        }///Buttonende


    }//Methodenende
}///Klassenende

Und mal die Klasse nebenbei:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    class Question
    {
        public string Frage { get; set; }
    

        public Question(string frage)
        {
            Frage = frage;
          
        }
    }
}

1.029 Beiträge seit 2010
vor 6 Jahren

Hi,

naja - was soll er auch anders machen in der foreach-Schleife?

Grundsätzlich sehe ich nach wie vor viele Logikprobleme deinerseits.

Zu deinem genannten Problem:
a) Nimm dir eine Zählervariable als Klassenvariable (int CurrentQuestionIndex = 0;)
b) Bei jedem Button-Click prüfst holst du dir anhand der Zählervariable die aktuelle Frage
c) Nach Ausgabe von "richtig/falsch" inkrementierst du die Zählervariable und setzt die neue Frage

Als Tipp: Es würde ggf. Sinn machen die möglichen Antworten, sowie die Richtige zugehörig zur Frage abzuspeichern.

LG

2.207 Beiträge seit 2011
vor 6 Jahren

Hallo Skydanith,

ja, du hast ja auch eine Foreach-Schleife. Was erwartest du, was die tut? Die macht ein foreach x in y. Alles, was du darin machst, wird für jedes Item ausgeführt. Und das spätestens sollte dich auf dein Problem stossen lassen. 😉

Deine Klasse ist zwar gut und schön, beinhaltet aber nur einen string. Da kannst du auch gleich einen String nehmen.

So wie Taipi88 das schon geschrieben hat: Mach dir doch die Klasse mit Frage und Antwort fertig und arbeite mit dem Objekt. Und einer Liste dieser Objekte. Dann brauchst du auch keine zweidimensionalen Arrays. Das hat mein Codeschnipsel dir auch gezeigt.

Deine Fragen kannst du dir in einer Klasse speichern (und ich kopiere hier das Snippet von oben)

class Question
{
        public string Text { get; private set; }
        public string Answer { get; private set; }

        public Question(string text, string answer)
        {
            Text = text;
            Answer = answer;
        }
}

Du kannst dir jetzt eine Liste mit Fragen erstellen...so in etwa:


 questions = new List<Question>()
{
        new Question("Frage1", "Antwort1"),
        new Question("Frage2", "Antwort2"),
        new Question("Frage3", "Antwort3"),
        new Question("Frage4", "Antwort4")
};

Eine Methode, die "Play" heissen kann, könnte dein Spiel darstellen und dir eine Rückgabe geben, ob die Antwort richtig war oder nicht. Die rufst du auf und schaust, ob der Rückgabewert true oder false ist. True: zähle den index hoch, false: zähle nicht hoch. Ist der Index gleich der Anzahl der Elemente bricht die Schleife ab und das Spiel ist zuende.

Aber das kannst du jetzt programmieren 😉

Gruss

Coffeebean

S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren

@taipi88

Das mit der foreach Schleife war nur ein Überbleibsel. Irgendetwas bewirkt hatte Sie in dem Code sowieso nicht.

Aber ich merke gerade, dass ich vermutlich noch nicht soweit bin für so ein Quiz oder gar nicht fürs programmieren geeignet bin.
Es ist auch so, dass ich soviel abgeändert habe ect, dass ich selbst den Überblick verloren habe.

Der Videokurs den ich gemacht habe, erklärte nur die grundlegenden Sachen. Z.b was eine for schleife macht, oder was eine Klasse ist, was eine Methode mit Rückgabewert und ohne Rückgabewert ist usw. Grundsätzlich verstehe ich alles, habe aber noch Probleme, dieses Wissen anzuwenden.

Mir ist klar, dass ich einen Fragenblock brauche und einen Antwortenblock. Dabei müssen beide Blöcke einen index besitzen, damit ich diesen mittels einer Schleife per Click durchlaufen lassen kann.

Da scheitert es aber noch an der praktischen Ausführung.

Naja.

16.842 Beiträge seit 2008
vor 6 Jahren

r gar nicht fürs programmieren geeignet bin.

Jeder kann es lernen 😉

S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren

Ajo,

ich werde mich jetzt einfach hinsetzen und das "Einstieg in C# mit Visual Studio 2017" einfach mal durchackern....
Da ich durch die Videos viel mehr weis wie vorher und WAS damit gemeint ist, dürfte ich es leichter haben.
Und ich werde jetzt erstmal von dem Gedanken Abstand nehmen mit aller Gewalt WPF Abstand zu nutzen und erstmal Windows Forms nehmen.

Dann lösen sich bestimmt viele Probleme von ganz alleine. Weil die Dinge von ihrer Mechanik zu kennen, heißt noch lange nicht, sie auch korrekt anwenden zu können.

Und bevor ich das Buch nicht durch habe, schreibe ich hier auch nichts mehr.

4.942 Beiträge seit 2008
vor 6 Jahren

Wenn du vorher nicht schon andere Programmiersprachen gelernt hast, d.h. C# deine erste ist, dann würde ich dir empfehlen, zuerst einmal ein paar reine Konsolenprogramme zu schreiben, wo du die Grundlagen von C# kennenlernst. Und erst wenn du das Grundverständnis für die C#-Anweisungen hast (Klassen, Arrays, Schleifen, ...), dann dich an WinForms zu versuchen (denn das ereignisorientierte Programmieren ist eine weitere Herausforderung).

S
Skydanith Themenstarter:in
20 Beiträge seit 2017
vor 6 Jahren

C# ist meine erste Programmiersprache und ich habe Ende August mit dem programmieren angefangen. Dann hatte ich mir einen Grundlagenkurs geholt auf Udemy. Anschließend kam ich auf die Idee eine Windows Forms Application zu machen.
Und hier stehe ich 😃

Aber ich werde deinen Rat befolgen.