C# Quiz - Antworten darstellen (Teil 4)

5 min read

Nachdem wir die Fragen anzeigen lassen können, werden wir uns jetzt um die Antworten kümmern.

Die Antworten sind ebenfalls im .xml Format gespeichert:

<antworten>
  <antwort id="1">Fast immer</antwort>
  <antwort id="2">Oft</antwort>
  <antwort id="3">Manchmal</antwort>
  <antwort id="4">Ganz selten</antwort>
</antworten>

Genauso wie die Fragen, sollen sich die Antworten anpassen und erweitern lassen.

Die Klasse Answers

Im letzten Teil haben wir die Basisklasse QuizXml erstellt. Diese können wir jetzt wieder für die Antworten verwenden. Das Grundgerüst sieht so aus:

class Answers : QuizXml
{
    private string[] str_answers;
    private RadioButton[] rdb_answers;

    /// <summary>
    /// Constructor
    /// </summary>
    public Answers() { }

    /// <summary>
    /// Returns an array of RadioButton Controls
    /// </summary>
    public RadioButton[] ArrAnswers { }

    private void ToRadioButton() { }
}

Der Konstruktor der abgeleiteten Klasse Answers legt sämtliche Properties fest und ruft die Methode PopulateArray() auf. Außerdem wird das Array initialisiert und selbiges in RadioButtons konvertiert.

public Answers()
{
    base.arr_data = new string[1];
    base.Path = "Antworten.xml";
    base.xmlElement = "antworten";
    base.xmlSub = "antwort";

    base.PopulateArray();

    this.str_answers = base.arr_data;

    this.ToRadioButton();
}

Neu ist eigentlich nur die Methode ToRadioButton():

private void ToRadioButton()
{
    rdb_answers = new RadioButton[base.Count];
    int index = 0;
    foreach (string answer in str_answers)
    {
        rdb_answers[index] = new RadioButton();
        rdb_answers[index].Name = "rdb_" + index;
        rdb_answers[index].Text = answer;
        rdb_answers[index].Top = 40 + (index * 30);
        rdb_answers[index].Left = 20;
        index++;
    }
}

Hier wird für jede vorhandene Antwort ein neuer RadioButton erzeugt. Außerdem wird ein EventHandler für das Click-Event festgelegt.

Die Eigenschaft ArrAnswers gibt das komplette RadioButton Array zurück:

/// <summary>
/// Returns an array of RadioButton Controls
/// </summary>
public RadioButton[] ArrAnswers
{
    get
    {
        return rdb_answers;
    }
}

Anwendung der Klasse im Fragebogen

Die Anpassung der Form ist recht einfach. Wir fügen der Methode Form1_Load() folgende Zeile hinzu:

this.Controls.AddRange(a.ArrAnswers);

Weiterhin soll man den Weiter-Button nicht benutzen können, bevor eine Antwort ausgewählt ist. Dazu wird die Eigenschaft enabled des Buttons button_next zunächst auf false gesetzt.

Wenn nun eine Antwort ausgewählt wird, soll der Button aktiviert werden. Dazu müssen wir jedem unserer RadioButtons einen EventHandler zuweisen.

Der EventHandler aktiviert den Button button_next wieder. Außerdem werden wir im letzten Teil dieser Reihe an dieser Stelle die Antworten sammeln.

In der Methode Form1_Load fügen wir jedem RadioButton einen Click-Eventhandler hinzu:

//Add an eventhandler for each radiobutton
foreach (RadioButton rdb in a.ArrAnswers)
{
    rdb.Click += Handler;
}

Die Methode Handler aktiviert den Weiter-Button wieder wenn ein Click-Event von einem der RadioButtons ausgeht.

/// <summary>
/// Eventhandler for the Radiobuttons.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Handler(object sender, EventArgs e)
{
    button_next.Enabled = true;
}

Nun muss noch die Methode button_next_Click() erweitert werden. Dort wird die vorherige Antwort und der Weiter-Button wieder deaktiviert:

private void button_next_Click(object sender, EventArgs e)
{
    UpdateQuestion();

    //deselect the last answer
    foreach (RadioButton rdb in a.ArrAnswers)
    {
        if (rdb.Checked == true)
        {
            rdb.Checked = false;
            break;
        }
    }

    button_next.Enabled = false;
}

Um zu verhinden, dass nach der letzten Frage die Antworten angezeigt werden, müssen wir die Methoden EndReached() und Restart() erweitern:

private void EndReached()
{
    //.
    //. //Skipped some lines here
    //.

    //Set all Answers invisible
    foreach (RadioButton rdb in a.ArrAnswers)
    {
        rdb.Visible = false;
    }
}

private void Restart()
{
    //.
    //. //Skipped some lines here
    //.

    //Set all Answers visible
    foreach (RadioButton rdb in a.ArrAnswers)
    {
        rdb.Visible = true;
    }
}

Das war’s auch schon. Wir können nun beliebige Fragen und Antworten ausgeben lassen und den Test wiederholen. Damit haben wir schon über die Hälfte unserer Anforderungen an das Programm erfüllt. Nun fehlt nur noch eine grafische Darstellung der Testergebnisse.

Die bisherige Lösung als .zip Datei: Nicht mehr verfügbar.

18 Sep 2010
blog comments powered by Disqus