Zum Inhalt springen
  • 0

C# Zugriff auf externe Klassen


Kackboon

Frage

Hallo Leute


Ich habe mal wieder eine vermutlich einfache Frage. Aktuell bastele ich an einer Windows Forms Anwendung, die einen Quiz-Character hat.

Idee des Programms:

Ich möchte die Zwischenprüfung aus vergangenen Jahren für Anwendungsentwickler in elektronische Form bringen. Viele der Fragen sind Multiple-Choice - also recht einfach zu programmieren. Andere erfordern etwas mehr Kreativität. Es soll natürlich auch eine automatische Punkteauswertung am Ende geben, die mir meine Punktzahl, den Prozentsatz etc. per IHK-Schlüssel ausgibt.

Eigentlich war die Idee eine extra Klasse zu erstellen, in der Ich diese Auswertung vornehme. Aktuell funktioniert die Auswertung so: Jede korrekt beantwortet Frage (korrekt ausgefüllte Checkbox) gibt einen Punkt. Dieser führt dazu, dass eine variable "Counter1" hochgezählt wird. Am ende unter der "Auswertung"-Klasse sollen die Counter einfach ganz normal addiert werden und führen zu einer Gesamtpunktzahl (Ich weiß es gibt bessere Ideen für die Auswertung, mir geht's nur erst einmal darum ein funktionierendes Konstrukt zu schaffen).

 

Das ganze sieht dann ungefähr so aus:

quizbild.thumb.png.a2c939f960d45e58c2c052be457be4bc.png

namespace Zwischenprüfung_Anwendungsentwickler
{
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }

     
        int counter1 = 0;
        bool Answer1 = false;

        public void button1_Click(object sender, EventArgs e)
        {          

            if (box2.Checked)
            {
                counter1++;               
            }
            else if (box1.Checked == false && box3.Checked == false && box2.Checked == false && box4.Checked == false && box5.Checked == false)
            {
                MessageBox.Show("Du solltest schon etwas anklicken..");                         
            }
            else
            {
                //MessageBox.Show("");
            }

            this.Hide();
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }
    }
}

Das Problem:

Wie man unschwer erkennen kann, habe ich für jede einzelne Frage eine neue Windows Form generiert. Das Führt natürlich dazu, dass ich in jeder einzelnen Form eine variable "Counter1", "Counter2" usw. angelegt habe. Diese werden auch hochgezählt bei korrekter Antwort. Allerdings möchte ich ja die Berechnung der Endpunktezahl in einer anderen Klasse durchführen..

 

Also meine Frage:

Wie kann ich auf die variablen der einzelnen Forms zugreifen, um diese dann in einer anderen Klasse "Auswertung" zu addieren?
wie kann ich generell auf andere Klassen zugreifen und deren Inhalte ausführen lassen?

 

Danke schonmal im voraus.

Link zu diesem Kommentar
Auf anderen Seiten teilen

25 Antworten auf diese Frage

Empfohlene Beiträge

  • 1
vor 33 Minuten schrieb Kackboon:

Jede Checkbox entspricht einem Zahlenwert. Bei jeweils 5 Checkboxen pro Frage ergeben sich die Werte: 1,2,4,8,16 . Dieses System ermöglicht es Rückschlüsse auf die gegebenen Antworten zu ziehen. Beispielsweise wenn bei Frage 1 die Antwortmöglichkeit 1 und 3 ausgewählt wurde, so ergibt sich der Zahlenwert 5 (1+4).

Das soll mir am ende dabei helfen die falschen Antworten zu finden.

Das ist viel zu kompliziert und ich garantiere dir, spätestens nach zwei Wochen verstehst du deinen eigenen Code auch nicht mehr. Wieso gehst du dort nicht pragmatischer ran? Stell dir doch vor, eine Aufgabe wäre ebenfalls eine Klasse. Welche Informationen bräuchtest du denn, um eine Multiple-Choice-Aufgabe abzubilden?

  • Aufgabentext
  • Lösungsvorschläge
  • Lösung

Daraus könnte man ja eine Klasse bauen:

public class Aufgabe
{
    public string Aufgabentext { get; }
    public string[] Lösungsvorschläge { get; }
    public int[] Lösung { get; }
  
    public Aufgabe(string aufgabentext, string[] lösungsvorschläge, int[] lösung)
    {
        this.Aufgabentext = aufgabentext,
        this.Lösungsvorschläge = lösungsvorschläge,
        this.Lösung = lösung
    }   
}

Damit könnte man ja nun eine Aufgabe definieren:

Aufgabe aufgabe1 = new Aufgabe(
    "Wie viel ist 1+1?",
    new string[] {"4", "3", "2", "5"},
    new int[] {2}
)

In Lösungen stehen dann die Indizes der richtigen Lösungen aus Lösungsvorschläge. Wenn man jetzt weiter überlegen würde, gehören die Lösungsvorschläge und die Lösungen doch irgendwie zusammen und zwar gibt es einen Vorschlag und der ist entweder richtig oder falsch. Also könnte man daraus wieder eine Klasse bilden:

public class Lösungsvorschlag
{
    public string Text { get; }
    public bool IstRichtig { get; }

    public Lösungsvorschlag{string text, bool istRichtig
    {
        this.Text = text;
        this.IstRichtig = istRichtig;
    }
}

Also könnte man die Aufgabenklasse ändern:

public class Aufgabe
{
    public string Aufgabentext { get; }
    public Lösungsvorschlag[] Lösungsvorschläge { get; }
  
    public Aufgabe(string aufgabentext, Lösungsvorschlag[] lösungsvorschläge)
    {
        this.Aufgabentext = aufgabentext;
        this.Lösungsvorschläge = lösungsvorschläge;
    }   
}

Der Aufruf sieht dann so aus:

Aufgabe aufgabe1 = new Aufgabe(
    "Wie viel ist 1+1?",
    new Lösungsvorschlag[] {
        new Lösungsvorschlag("4", false),
        new Lösungsvorschlag("3", false), 
        new Lösungsvorschlag("2", true),
        new Lösungsvorschlag("5", false)
    }
);

Du hast hier dann eine Struktur, mit der es möglich ist, ohne Mathematikkünste herauszufinden, welche Antwort richtig und falsch ist. Wenn man das jetzt weiterspinnt, dann könnte man daraus auch eine Textdatei machen, die eingelesen wird und daraus die Aufgaben-Objekte erzeugt.

Eine weitere Klasse könnte ja dann die Auswertung übernehmen. Sie würde dann die Aufgabe und die Lösungen vom Benutzer bekommen und miteinander vergleichen.

Wenn man die Probleme in kleinere Probleme aufteilt, dann benötigt man später keine allzugroßen Algorithmen und auch keine große "Magic". Der Code wird dadurch auch lesbarer und verständlicher.

vor einer Stunde schrieb Kackboon:

Das hat bereits funktioniert indem ich die variable einfach public static gemacht habe.

So was wie public static (oder allgemein static) sollte man auch vermeiden. Das sollte schon einen sehr guten Grund haben, warum man sowas machen möchte und nicht einfach nur, weil man es nicht besser weiß. static hat nun mal das Problem, dass es sich um eine Eigenschaft der Klasse handelt und nicht des Objektes, was dann zu unvorhergesehenen Verhalten der Objekte führen kann, da statische Werte überall verändert werden können. Angenommen, du arbeitest in einem größeren Projekt mit 1.000 Klassen und das Verhalten eines oder mehrere Objekte ändern sich. Angenommen, du hast mehrere Maschinen, die Nägel in ein Stück Holz hämmern und für die Maschinen gibt es ein gemeinsames Magazin für die Nägel und jemand tauscht die Nägel irrtümlicherweise gegen Kaugummi aus und jetzt versucht jede Maschine Kaugummi in das Holz zu hämmern und die gesamte Produktion steht still. Es wäre dann sinnvoller,  jede Maschine hätte ihr eigenes Magazin und es würde dann nur eine Maschine ausfallen.

vor einer Stunde schrieb Kackboon:

Ich bin noch ziemlich am Anfang mit dem programmieren wie man hier vllt. deutlich merkt.

Darum würde ich dir auch dazu raten, mit einer Konsolenanwendung anzufangen, anstatt mit einer Anwendung mit einer grafischen Oberfläche, um überhaupt ein Gefühl für die Sprache zu bekommen. Auch wenn Schulen immer was anderes suggieren und dann irgendwas zurecht frickeln, braucht man bei grafischen Oberflächen schon ein Verständnis für die Sprache und wie solche Oberflächen funktionieren. Auch wenn es schön einfach ist, einfach ein Button in die Form zu schieben und dann per Doppelklick das Event zu implementieren, so ist dies auch schon ein sehr schlechter Weg, um eine Anwendung zu bauen. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Erstmal würde ich nicht für jede Aufgabe eine eigene Form bauen. Das widerspricht dem kompletten Gedanken der Objektorientierung. 
Ich würde also erst mal anfangen, zu überlegen, welche Arten von Aufgaben du hast (Multiple Choice, Rechenaufgabe, ...) und dafür geeignete Forms ausdenken. Eine Aufgabe kann ja selber eine Klasse sein.

Deine "externe Klasse", die die Auswertung übernimmt kannst du ja per Dependecy Injection reinreichen.

https://blogs.msdn.microsoft.com/dmx/2014/10/14/was-ist-eigentlich-dependency-injection-di/

Deine Forms besitzen dann eine Property, die als Typ deine "externe Klasse" entspricht. Bei der Instanziierung der Form reichst du dann deine "externe Klasse" rein. Beispiel:

public class AnalysisClass
{
    // ...
}

public class MyForm : Form
{
	public MyAnalysisClass AnalysisClass { get; set; }
	/// ...
}
AnalysisClass analysisClass = new AnalysisClass();

MyForm myForm = new MyForm();
myform.AnalysisClass = analysisClass;

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Erstmal ist das, was @Whiz-zarD geschrieben hat, richtig. Vielleicht hilft's dir aber, wenn man ein wenig simpler einsteigt.

vor 5 Stunden schrieb Kackboon:

Wie kann ich auf die variablen der einzelnen Forms zugreifen, um diese dann in einer anderen Klasse "Auswertung" zu addieren?

Um die Variable "von außen" sehen zu können, muss sie "public" sein. Das bedeutet:

// statt dem hier:
int counter1 = 0;

// muss das so aussehen:
public int counter1 = 0;

// in C# sind öffentliche Felder aber eher verpöhnt, daher
// nutzt man normalerweise Properties. Die Feinheiten sind 
// hier eher egal - sollte man sich aber angewöhnen
public int Counter1 { get; set; }

 

vor 5 Stunden schrieb Kackboon:

wie kann ich generell auf andere Klassen zugreifen und deren Inhalte ausführen lassen?

So, dein Counter ist jetzt also von außen einsehbar. Wie kommst du jetzt da dran? Recht einfach:

// eine Variable zur Speicherung der Gesamtsumme
int counterSum = 0;

// hiermit erzeugst du eine neue Instanz deines Formulars
MyForm form = new MyForm();
// hier wird das Formular angezeigt
form.ShowDialog();
// nach der Anzeige kannst du den Counter aus dem Formular
// auf deine Summe draufaddieren
counterSum += form.Counter1;

Das ist so ziemlich die Grundlage von OO. Du erzeugst dir Objekte (Instanzen von Klassen), arbeitest mit denen und greifst von anderen Objekten auf diese zu.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Also vielen Dank erst einmal für die schnellen Antworten.

 

@arlegermi Das hat tatsächlich geholfen. Mir ist es wichtig das ganze erst einmal zum laufen zu bringen bevor ich das Ding in irgendeiner Form optimiere. Ich bin mittlerweile schon ein wenig weiter und es ergibt sich direkt die nächste Frage.. ^^

Ich versuche aktuell die Auswertung meines Programms zum laufen zu bringen. Und zwar habe ich wie im Bild oben zu sehen diverse Multiple-Choice Fragen, deren checkbox-Status einen Zahlenwert liefert. Diesen versuche ich dann in der Auswertungs-Klasse auszulesen. Dabei kann ich mittlerweile auf die variablen aus anderen Forms zugreifen dank eurer Tipps. Diese Zahlenwerte werden dann in Punkte umgewandelt und es ergibt sich eine Endpunktzahl.

Jetzt hatte ich mir überlegt, dass ich auch gerne den Prozentsatz anzeigen lassen möchte. Dazu folgender Code der Auswertungs-Klasse:

public class Global
    {
        public static int counterall = 0;
        public static double prozent = (counterall / 11.00);

        public static void Auswertung()
        {


            Form1 Form11 = new Form1();
            Form2 Form12 = new Form2();
            Form3 Form13 = new Form3();
            Form4 Form14 = new Form4();
            Form5 Form15 = new Form5();
            Form6 Form16 = new Form6();
            Form7 Form17 = new Form7();


            if (Form1.counter1 == 2)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 1 leider falsch!");
            }

            if (Form2.counter2 == 1)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 2 leider falsch!");
            }

            if (Form3.counter3 == 8)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 3 leider falsch!");
            }

            if (Form4.counter4 == 8)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 4 leider falsch!");
            }

            if (Form5.counter5 == 4)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 5 leider falsch!");
            }

            if (Form6.counter6 == 6 || Form6.counter6 == 2 || Form6.counter6 == 4)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 6.1 leider falsch!");
            }

            if (Form6.counter7 == 6 || Form6.counter6 == 2 || Form6.counter6 == 4)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 6.2 leider falsch!");
            }

            if (Form6.counter8 == 2)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 6.3 leider falsch!");
            }

            if (Form6.counter9 == 2)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 6.4 leider falsch!");
            }

            if (Form6.counter6 == 4)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 6.5 leider falsch!");
            }

            if (Form6.counter6 == 1)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 6.6 leider falsch!");
            }


            MessageBox.Show(counterall.ToString());
            MessageBox.Show(prozent.ToString());


        }            
    }    
}

So sieht aktuell die Auswertungs-Form aus:

Auswertung.png.868fbd45c4fd8db25e0f264ef86e4344.png

Und hier der Code dazu:

namespace Zwischenprüfung_Anwendungsentwickler
{
    public partial class Form7 : Form
    {
        public Form7()
        {
            InitializeComponent();
        }

        private void label3_Click(object sender, EventArgs e)
        {

        }


        public void button1_Click(object sender, EventArgs e)
        {
            //Global g1 = new Global();

            Global.Auswertung();
            MessageBox.Show(Global.counterall.ToString());
            textBox1.Text = Global.counterall + " Punkte / 11 Punkten";
            //textBox2.Text = (Convert.ToDouble(Global.counterall / 11)) + " %";
            textBox2.Text = Global.prozent + " %";


            Global.counterall = 0;
            
            
        }
    }
}

Wie man unten sieht habe ich einen double "prozent" erstellt, der mir nun in der textbox2 angezeigt werden soll. Allerdings zeigt er mir ständig nur eine "0" an... Egal wie ich es versuche. Die variable "counterall" einfach in double zu konvertieren und anzeigen zu lassen habe ich auch versucht - vergeblich.

Weiß jemand was ich falsch mache?

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Ich muss sagen ich finde das ganze gerade total schwer zu lesen und nachzuvollziehen.
Wie sieht den aktuell die Implementierung deiner Form Klassen aus?

Folgendes ist für mich auch nicht ganz nachvollziehbar

 Form1 Form11 = new Form1();
            Form2 Form12 = new Form2();
            Form3 Form13 = new Form3();
            Form4 Form14 = new Form4();
            Form5 Form15 = new Form5();
            Form6 Form16 = new Form6();
            Form7 Form17 = new Form7();

Warum instanziierst du neue Form Objekte, benutzt diese aber im nachfolgenden Kontext nicht.

Global.Auswertung();

Möchtest du damit erreichen das du auf die Ergebnisse der einzelnen Forms zugreifst bzw. ermittelst?

Form1.counter1 == 2

Würde doch auf eine statische Variable der Form1 Klasse zugreifen.

Ein wenig mehr Erklärung zum Code wäre glaube ich ziemlich hilfreich. Vor allem was du mit den entsprechenden Codepassagen erreichen möchtest.

   Form1 Form11 = new Form1();
            Form2 Form12 = new Form2();
            Form3 Form13 = new Form3();
            Form4 Form14 = new Form4();
            Form5 Form15 = new Form5();
            Form6 Form16 = new Form6();
            Form7 Form17 = new Form7();


            if (Form1.counter1 == 2)
            {
                counterall++;
            }
            else
            {
                MessageBox.Show("Antwort 1 leider falsch!");
            }

Dieser Abschnitt bzw. die komplette Klasse ist für mich nicht wirklich nachvollziehbar.
Allen voran das instanziieren der einzelnen Forms und anschließend der Zugriff auf die statischen Eigenschaften.

@arlegermi hat dir bereits ein Input mit der AnalysisClass und dem Injecten der Klasse in deine Form gezeigt. Wo ist dies untergebracht?

Bearbeitet von r4phi
Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
Form1 Form11 = new Form1(); 
Form2 Form12 = new Form2(); 
Form3 Form13 = new Form3(); 
Form4 Form14 = new Form4(); 
Form5 Form15 = new Form5(); 
Form6 Form16 = new Form6(); 
Form7 Form17 = new Form7();

Was dir hier fehlt, ist die Fenster auch aufzurufen. Sprich, etwas in der Art

Form1 Form1 = new Form1();

Form1.ShowDialog(); // hiermit bringst du das Fenster zur Anzeige

//nachdem das Fenster wieder zu ist, kannst du den Wert abfragen:
int summe += Form1.Counter;

Im Grunde würde "man" so ein Programm ungefähr so aufbauen (stark vereinfacht und sicher nicht "perfekt"):

public StartForm : Form
{
  Form[] quizFragen = new Form[5] { new Form1(), new Form2(), new Form3(), new Form4(), new Form5() };
  
 public void StartQuiz()
 {
   int summe = 0;
   for(int i = 0; i < quizFragen.Length; i++)
   {
     quizFragen[i].ShowDialog();
     summe += quizFragen[i].Counter; // <-- das hier funktioniert so nicht direkt; weißt du, wieso?
   }
   
   ZeigeAuswertung(summe);
 }
  
  public void ZeigeAuswertung(int punktzahl)
  {
   ResultForm resultForm = new ResultForm();
    resultForm.Ergebnis = punktzahl;
    resultForm.ShowDialog(); // auf dem ResultForm zeigst du dann deine Auswertung
  }
}

Wie gesagt: Das ist stark vereinfacht, aber grundsätzlich die Art und Weise, auf die man so etwas lösen kann. Man kann da auch noch viel weiter gehen (in die Richtung, die @Whiz-zarD mit Dependency Injection angesprochen hat, z.B.) - aber für den Anfang wär's erstmal ganz wichtig, dass du dich mit Dingen wie Arrays, Schleifen und Objekten an sich auseinandersetzt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 16 Stunden schrieb r4phi:

Form1 Form11 = new Form1(); Form2 Form12 = new Form2(); Form3 Form13 = new Form3(); Form4 Form14 = new Form4(); Form5 Form15 = new Form5(); Form6 Form16 = new Form6(); Form7 Form17 = new Form7();

Dieser Part stammt noch von der alten Version der Auswertung, habe das mittlerweile aus dem code entfernt.

vor 16 Stunden schrieb r4phi:

Global.Auswertung();

Der part führt die Methode in der anderen Klasse aus. Also die IF-Abfragen und das hochzählen der gesamtpunktezahl.

 

vor 16 Stunden schrieb r4phi:

Möchtest du damit erreichen das du auf die Ergebnisse der einzelnen Forms zugreifst bzw. ermittelst?


Form1.counter1 == 2

Damit soll er sich den Counter in der Form1 ansehen, und wenn dieser den Wert 2 hat den Gesamtpunktecounter hochzählen. Also ja.

Dazu vllt. eine kleine Erklärung:

Jede Checkbox entspricht einem Zahlenwert. Bei jeweils 5 Checkboxen pro Frage ergeben sich die Werte: 1,2,4,8,16 . Dieses System ermöglicht es Rückschlüsse auf die gegebenen Antworten zu ziehen. Beispielsweise wenn bei Frage 1 die Antwortmöglichkeit 1 und 3 ausgewählt wurde, so ergibt sich der Zahlenwert 5 (1+4).

Das soll mir am ende dabei helfen die falschen Antworten zu finden.

@arlegermi 

vor 15 Stunden schrieb arlegermi:

Was dir hier fehlt, ist die Fenster auch aufzurufen. Sprich, etwas in der Art


Form1 Form1 = new Form1();

Form1.ShowDialog(); // hiermit bringst du das Fenster zur Anzeige

//nachdem das Fenster wieder zu ist, kannst du den Wert abfragen:
int summe += Form1.Counter;

Das habe ich ausprobiert, allerdings verstehe ich nicht, wozu das gut sein soll? Dieses aufrufen mache ich bereits an einer anderen Stelle und zwar immer am ende einer Form z.B. hier:

 this.Hide();
            Form7 f7 = new Form7();
            f7.ShowDialog();

Es ging mir ja nur darum auch Zugriff auf die variablen in diesen Formen zu bekommen von einer anderen klasse aus. Das hat bereits funktioniert indem ich die variable einfach public static gemacht habe.

Ich bin noch ziemlich am Anfang mit dem programmieren wie man hier vllt. deutlich merkt. Diese Begriffe wie dependency-injection etc. sagen mir auch nicht wirklich etwas bzw. wie genau das funktioniert müsste ich googeln.

Mein Plan war erst einmal das Ding - irgendwie - zum laufen zu bringen und dann zu schauen was man alles noch vereinfachen kann. Denn ständig den Plan über den Haufen zu werfen weil es ja anders irgendwie leichter wäre und dann völlig anders an die Sache heran zu gehen verwirrt eher als das es hilft. Also insofern suche ich zunächst Antworten auf die - mehr oder minder - präzisen Fragestellungen die ich habe. Zum Beispiel: warum zum Geier gibt er mir bei dem Prozentwert ständig nur eine " 0 " zurück statt das Ergebnis ( 9 / 11 ) als double anzuzeigen wie ich es ihm eigentlich gesagt habe^^ ?

 

Hoffe das ist ein wenig verständlicher. Gebt mich nicht zu schnell auf :D

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 24 Minuten schrieb Kackboon:

Zum Beispiel: warum zum Geier gibt er mir bei dem Prozentwert ständig nur eine " 0 " zurück statt das Ergebnis ( 9 / 11 ) als double anzuzeigen wie ich es ihm eigentlich gesagt habe^^ ?

Hast du dein Programm bereits debugged und geprüft ob in

Global.counterall

ein Wert > 0 enthalten ist?

Um es zu verstehen:

  • Du hast pro Quizfrage eine Form()
  • Jede Form hat eine public static Variable (counterX) in welcher du das Ergebnis der jeweiligen Form speicherst
  • Für die Auswertung gehst du jeder dieser Forms durch und greifst auf die public static Variable zu
  • Entspricht die public static Variable einem bestimmten Wert zählst du den Counter hoch

Ist das so korrekt?

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor einer Stunde schrieb Kackboon:

Dwarum zum Geier gibt er mir bei dem Prozentwert ständig nur eine " 0 " zurück statt das Ergebnis ( 9 / 11 ) als double anzuzeigen wie ich es ihm eigentlich gesagt habe^^ ?

Weil du prozent nur ein einziges Mal berechnest, zu einem Zeitpunkt, an dem counterall 0 ist. Die Variable prozent aktualisiert sich nicht automatisch mit, wenn du counterall änderst.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 53 Minuten schrieb Kackboon:

indem ich die variable einfach public static gemacht habe

Ah, das hatte ich nicht gesehen. Dann ist das tatsächlich nicht relevant, was ich geschrieben habe.

In dem Fall schließe ich mich @r4phi an und schlage vor, dass du mal mit dem Debugger durch dein Programm durchgehst und guckst, welche Werte da denn tatsächlich auftauchen. Eine kleine Einführung zum Debugger gibt's bspw. hier: https://msdn.microsoft.com/de-de/library/mt243867.aspx

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 19 Minuten schrieb r4phi:

Hast du dein Programm bereits debugged und geprüft ob in


Global.counterall

ein Wert > 0 enthalten ist?

Um es zu verstehen:

  • Du hast pro Quizfrage eine Form()
  • Jede Form hat eine public static Variable (counterX) in welcher du das Ergebnis der jeweiligen Form speicherst
  • Für die Auswertung gehst du jeder dieser Forms durch und greifst auf die public static Variable zu
  • Entspricht die public static Variable einem bestimmten Wert zählst du den Counter hoch

Ist das so korrekt?

Gut zusammengefasst. Genau so ist das.

 public void button1_Click(object sender, EventArgs e)
        {
            //Global g1 = new Global();

            Global.Auswertung();
            MessageBox.Show(Global.counterall.ToString());  // gibt mir den Wert der variable zurück 
            textBox1.Text = Global.counterall + " Punkte / 11 Punkten";
            //textBox2.Text = (Convert.ToDouble(Global.counterall / 11)) + " %";
            textBox2.Text = Global.prozent + " %";


            Global.counterall = 0;  //soll verhindern, dass wenn man erneut auf "Auswerten" klickt der counter einfach addiert wird.
            
        }

Habe mir extra eine MessageBox ausgeben lassen um zu prüfen ob der counterall wirklich den korrekten Wert hat. Also das stimmt soweit.

 public class Global
    {
        public static int counterall = 0;
        public static double prozent = (counterall / 11.00);

        public static void Auswertung()
        {

Und hier sage ich ja quasi dass die variable "prozent" der variable "counterall" (z.B. 9) / 11.00 (extra im double-Format zur Sicherheit^^) entsprechen soll.

Müsste doch also eigentlich gehen oder nicht ?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 3 Minuten schrieb Klotzkopp:

Weil du prozent nur ein einziges Mal berechnest, zu einem Zeitpunkt, an dem counterall 0 ist. Die Variable prozent aktualisiert sich nicht automatisch mit, wenn du counterall änderst.

Diese Vermutung hatte ich auch bereits. Daraufhin hatte ich dann versucht die variable einfach unter der ganzen counterall-hochzähl-geschichte zu deklarieren. Dies führte allerdings zu diversen anderen Fehlern. Beispielsweise wird mir alles nach der Deklaration der variable rot markiert. Also jede darauf folgende Zeile. "... ist im Kontext nicht verfügbar"

Außerdem sagt er mir dann, dass irgendwo Klammern fehle..

Alternativ dachte ich, dass ich diese Prozent variable einfach in der Form 7 generiere und nicht in der Auswertung-Klasse, dann fehlt mir allerdings der Zugriff auf die "counterall" variable, die sich ja in der Auswertung-Klasse befindet.

Zweite alternative war ja auch, dass ich einfach die counterall variable in double konvertiere. Vom Syntax hat's gepasst was ich da eingehackt habe, führte allerdings zum selben Ergebnis -> "0"..

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Ahh Okay.
Verstehe.

Dein Problem ist das hier

  public static double prozent = (counterall / 11.00);

Den:

vor 9 Minuten schrieb Kackboon:

(z.B. 9) / 11.00

Ergibt einen Wert < 1 (0,8181818181818182) . Da du mit einem int Dividend arbeitest kommt als Ergebnis 0 raus.
Die Umwandlung in einen double geschieht nämlich nach der Kalkulation!

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Ach. Vergiss es.
Mein Fehler.
Hast recht.
Ich mache nichts mehr auf die schnelle.

So sollte es passen

public static class Global
    {
        public static int CounterAll = 0;
        public static double Prozent
        {
            get
            {
                return CounterAll / 11.0;
            }
        }        
    }

... ich lasse Programmierung links liegen und wechsel in den Vertrieb :facepalm:

 


 
Bearbeitet von r4phi
Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 51 Minuten schrieb Kackboon:

public static double prozent = (counterall / 11.00);

VS

 

vor 12 Minuten schrieb r4phi:

Ach. Vergiss es.
Mein Fehler.
Hast recht.
Ich mache nichts mehr auf die schnelle.

So sollte es passen


public static class Global
    {
        public static int CounterAll = 0;
        public static double Prozent
        {
            get
            {
                return CounterAll / 11.0;
            }
        }        
    }


 

Wo ist denn da der Unterschied? Im Prinzip hab ich doch genau das selbe gemacht, nur bei mir funktioniert es nicht.

Deine Version haut aus mir nicht erischtlichen Gründen hin.

Eine variable public static double und diese soll den Wert  counterall / 11.00 haben..

Ich steh aufm Schlauch.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0
vor 4 Minuten schrieb Kackboon:

Eine variable public static double und diese soll den Wert  counterall / 11.00 haben..

Du kannst für Variablen keine "Berechnungsvorschriften" im Code hinterlegen. Das geht einfach nicht.

Unter anderem dafür gibt es Properties. Der Getter wird jedesmal ausgeführt, wenn lesend darauf zugegriffen wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

Kleines Update:

 

Habe mittlerweile die Auswertung abgeschlossen. Er zeigt mir jetzt die Punkte an, den Prozentwert usw. Die nächste Idee war eine Art "Highscore"  einzurichten. Dazu habe ich sobald man den Button "Auswerten" betätigt eine neue Form erstellen lassen. In diese habe ich ein ListView Objekt hereingezogen (Windows Forms) und mit entsprechenden spalten und Werten befüllt (statisch). Der Plan ist bei druck auf den "Auswerten"- Button den statischen Eintrag in der ListView zu ersetzen und zwar durch den Inhalt der TextBoxen, die ich am Anfang des Tests in der ersten Form habe ausfüllen lassen.

Das sieht dann so aus:

      1)      Anfang.png.40e10e340059461980dfef4b28cbc3ad.png

     2)       auswertung.png.b6a38707a35be822ab08a0faecb6c8e0.png

 

     3)       bestenliste.png.e003e94ff13522579298f41496d2785b.png

 

Lasst euch nicht von der Reihenfolge bei der Benamsung der Forms irritieren..

 

Es ergibt sich mal wieder das Problem mit dem Zugriff auf besagte Labels und andere Objekte (ListView, Methoden, etc..) 

Wenn ich also auf "Auswerten" klicke möchte ich, dass er die Inhalte der TextBoxen aus 1) nimmt und diese sollen dann die Werte aus 3) ersetzen. Gibt bestimmt bessere Pläne wie man mit diesem LiestView umgehen kann zu diesem zwecke, aber da ich damit noch nie gearbeitet habe ist mir nichts besseres eingefallen.

Ich habe eine "ersetzen" Methode in Form6 geschrieben, die so aussieht:

 public void ersetzen()
        {            
            listView1.Items[1].SubItems[1].Text = form5bla;
        }

        public static string form5bla;
        
        

Die variable form5bla wird von meiner form5 so verwendet:

 public void textBox1_TextChanged(object sender, EventArgs e)
        {
            Form6.form5bla = textBox1.Text;
        }

nun versuche ich diese in meiner Auswertungsform (Form2) aufzurufen:

Form6.ersetzen(); //für das nicht statische feld, die methode oder eigenschaft "Form6.ersetzen();" ist ein Objektverweis erforderlich

...

geht nicht. Ich weiß nicht was ich noch machen soll.

Hoffe das war irgendwie für irgendjemanden verständlich. Falls nicht helfe ich gern.

 

bestenliste.png

Bearbeitet von Kackboon
bla
Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 0

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

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties

 

Erstmal solltest du das Lesen und verstehen. Es bringt nichts, wenn wir dir Code hinwerfen, wenn du gar nicht verstehst warum du etwas wie machst. 

Du weißt bisher noch nicht viel. Du kannst dir nett was zusammenklicken und Eigenschaften ändern, aber du verstehst noch nicht wie du mit Objekten umgehst.

Ansonsten guck dir nochmal die Vorschläge von @Whiz-zarD an

Bearbeitet von KeeperOfCoffee
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...