WPF C# Tutorial – Create a simple quiz game in Visual Studio

Hello and welcome to a new programming tutorial from MOO ICT. In this tutorial we will show you how to make a simple quiz game inside of Visual Studio using C# and WPF Programming. This quiz game will be a multiple-choice quiz game template for you to use in your own projects. We will not provide any images or the questions for the quiz game however we will show you how to import your own images and make your own questions using this simple template. This quiz game is a new and improved version of the windows form C# quiz game we have done before and this one will you how to randomize the questions when the game starts and when the game ends. It’s a very unique way to make this type of game in WPF as we will be using the Canvas Element to set up the GUI for this game and then go into the more detailed C# programming.

Lesson Objectives –

  • Create a multiple-choice quiz game inside of visual studio with C# and WPF
  • Randomize the questions when the game starts so no two games are the same when they load
  • Add 10 questions using the SWITCH Statement
  • Use a LIST to add a list of questions to the game and shuffle the items inside of the LIST
  • Add images to each question
  • Identify the right answer from the wrong ones in the multiple choice
  • Keep track of the score throughout the game
  • Restart the game

 

Video Tutorial –

 

XAML Code for this game –

<Window x:Class="Quiz_Game_WPF_MOO_ICT.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Quiz_Game_WPF_MOO_ICT"
        mc:Ignorable="d"
        Title="Simple Quiz Game WPF MOO ICT" Height="600" Width="800">
    <Canvas Name="myCanvas" Background="DarkGray">

        <Label Name="scoreText" FontSize="18">Score: 0/10</Label>
        <Label Name="questionOrder" FontSize="18" Canvas.Left="349">Questions</Label>

        <Image Name="qImage" Source="images/1.jpg" Stretch="Uniform" Height="286" Width="572" Canvas.Left="104" Canvas.Top="39" />

        <TextBlock Name="txtQuestion" TextAlignment="Center" Padding="3" FontSize="20" Width="572" TextWrapping="Wrap" Canvas.Left="104" Canvas.Top="330">
            Hi welcome to this quiz game and we will be showing lots of different questions and you will click on the answer buttons to answer them.
        </TextBlock>

        <Button Background="DarkSalmon" FontSize="18" Click="checkAnswer" Name="ans1" Width="200" Height="50" Content="Answer 1" Tag="0" Canvas.Left="104" Canvas.Top="434" />
        <Button Background="DarkSalmon" FontSize="18" Click="checkAnswer" Name="ans2" Width="200" Height="50" Content="Answer 2" Tag="0" Canvas.Left="104" Canvas.Top="509" />
        <Button Background="DarkSalmon" FontSize="18" Click="checkAnswer" Name="ans3" Width="200" Height="50" Content="Answer 3" Tag="0" Canvas.Left="476" Canvas.Top="434" />
        <Button Background="DarkSalmon" FontSize="18" Click="checkAnswer" Name="ans4" Width="200" Height="50" Content="Answer 4" Tag="0" Canvas.Left="476" Canvas.Top="509" />


    </Canvas>
</Window>

In the XAML you can see we are using the CANVAS element instead of the GRID, a game such as this one you can use the GRID element as well we are not moving anything from the game or doing any sort of animation, in this case this is more of a personal preference to use the Canvas rather than the GRID, you can try to use it yourself and see it goes.

We have two labels on the top of the screen. For the first one it will be used for keeping score of how many questions we answered right and second label will show the order of questions to come. The question order label will be linked to the LIST which will be randomized each time the game loads and the game restarts. Inside of each tag we stated the options for them such as name, font size, canvas left and top options these will affect the component directly inside of the canvas and you can see them change inside the preview window.

After the two labels we have the image component, this component will load the images relative to each question. For this example I have 10 different JPG images loaded to the game and it will load one by one with each question.

The text block element will hold the question. It has a text wrap option enabled to it and it has its own height and width assigned too. We done it this way so we can write a long question on there and it will wrap the text inside of it and show it right under the image.

After the text block we have 4 different buttons displaying different answers for each question. As the questions change inside of the game so will the answers inside of it, for each button you have a back ground color, font size, CLICK EVENT, name and few other options.

C# Code for the Quiz Game

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 Quiz_Game_WPF_MOO_ICT
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // create a new list of integers called question numbers
        // this interger will hold how many questions we have for this quiz and we will shuffle this inside the start game function
        List<int> questionNumbers = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        // create 3 more integers called qNum that will control which question shows on the screen, i and score
        int qNum = 0;
        int i;
        int score;


        public MainWindow()
        {
            InitializeComponent();

            // inside of the main constructor we will run the start game and next question function

            StartGame();
            NextQuestion();
        }

        private void checkAnswer(object sender, RoutedEventArgs e)
        {
            // this is the check answer event, this event is linked to each button on the canvas
            // when either of the buttons will be pressed we will run this event

            Button senderButton = sender as Button; // first check which button sent this event and link it to a local button inside of this event

            // in the if statement below we will check if the button clicked on has a 1 tag inside of it, if it does then we will add 1 to the score
            if (senderButton.Tag.ToString() == "1")
            {
                score++;
            }

            // if the qnum is less than 0 then we will reset the qnum integer to 0
            if (qNum < 0)
            {
                qNum = 0;
            }
            else
            {
                // if the qnum is greater than 0 then we will add 1 to the qnum integer
                qNum++;
            }

            // update the score text label each time the buttons are pressed
            scoreText.Content = "Answered Correctly " + score + "/" + questionNumbers.Count;

            // run the next question function
            NextQuestion();

        }

        private void RestartGame()
        {
            // restart game function will load all of the default values for this game
            score = 0; // set score to 0
            qNum = -1; // set qnum to -1
            i = 0; // set i to 0
            StartGame(); // run the start game function
        }

        private void NextQuestion()
        {
            // this function will check which question to show next and it will have all of the question and answer definitions

            // in the if statement below it will checking if the qnum integer is less than the total number of questions if it then we will set the value of i to the value of qnum

            if (qNum < questionNumbers.Count)
            {
                i = questionNumbers[qNum];
            }
            else
            {
                // if we have done below the number of questions we have available then we will restart the game
                RestartGame();
            }

            // below we are running a foreach loop where will check for each button inside of the canvas and when we find them we will set their tag to 0 and background to dakr salmon colour
            foreach (var x in myCanvas.Children.OfType<Button>())
            {
                x.Tag = "0";
                x.Background = Brushes.DarkSalmon;
            }


            // below you have all of the question and answers template
            // you can add your own questions to the txtQuestion section
            // and add your own answers inside of the ans1, ans2, ans3 content and so. 


            // this switch statement will check what value is inside of i integer and show the questions based on that value

            switch (i)
            {
                case 1:

                    txtQuestion.Text = "Question 1"; // this the question for the quiz

                    ans1.Content = "Answer 1"; // each of the buttons can have their own answers in this game
                    ans2.Content = "Answer 2 Correct";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4";

                    ans2.Tag = "1"; // here we tell the program which one of the answers above is the right answer by adding the 1 inside of the tag for the button. 
                    // in this example we adding 1 inside of ans2 or button 2
                    // so when the button is clicked the game will know which is the correct answer and it add 1 to the score for the game

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/1.jpg")); // here we will load the 1st image inside of the qimage 

                    break; // when this condition is met the program will break the switch statement here and wait for the next one
                    // rest of the condition will follow the same principle as this one

                case 2:

                    txtQuestion.Text = "Question 2";

                    ans1.Content = "Answer 1 Correct";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4";

                    ans1.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/2.jpg"));

                    break;

                case 3:

                    txtQuestion.Text = "Question 3";

                    ans1.Content = "Answer 1";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3 Correct";
                    ans4.Content = "Answer 4";

                    ans3.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/3.jpg"));

                    break;

                case 4:

                    txtQuestion.Text = "Question 4";

                    ans1.Content = "Answer 1";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4 Correct";

                    ans4.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/4.jpg"));

                    break;

                case 5:

                    txtQuestion.Text = "Question 5";

                    ans1.Content = "Answer 1 Correct";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4";

                    ans1.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/5.jpg"));

                    break;
                case 6:

                    txtQuestion.Text = "Question 6";

                    ans1.Content = "Answer 1";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3 Correct";
                    ans4.Content = "Answer 4";

                    ans3.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/6.jpg"));

                    break;
                case 7:

                    txtQuestion.Text = "Question 7";

                    ans1.Content = "Answer 1";
                    ans2.Content = "Answer 2 Correct";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4";

                    ans2.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/7.jpg"));

                    break;
                case 8:

                    txtQuestion.Text = "Question 8";

                    ans1.Content = "Answer 1";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4 Correct";

                    ans4.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/8.jpg"));

                    break;
                case 9:

                    txtQuestion.Text = "Question 9";

                    ans1.Content = "Answer 1";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3 Correct";
                    ans4.Content = "Answer 4";

                    ans3.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/9.jpg"));

                    break;

                case 10:

                    txtQuestion.Text = "Question 10";

                    ans1.Content = "Answer 1 Correct";
                    ans2.Content = "Answer 2";
                    ans3.Content = "Answer 3";
                    ans4.Content = "Answer 4";

                    ans1.Tag = "1";

                    qImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/10.jpg"));

                    break;
            }
        }

        private void StartGame()
        {
            // this is the start game function
            // inside of this function we will randomise the questions list and save it back into the list 

            // create a new randomlist variable and use the line below to randomise the order of the content
            var randomList = questionNumbers.OrderBy(a => Guid.NewGuid()).ToList();

            // save the random list to the question numbers list again
            questionNumbers = randomList;

            // empty the question order label on the canvas
            questionOrder.Content = null;

            // run a for loop to add the value which will display the randomised list to the display so we can see how the list has been ramdomised
            for (int i = 0; i < questionNumbers.Count; i++)
            {
                questionOrder.Content += " " + questionNumbers[i].ToString();
            }

        }
    }
}

 

 




Comments are closed.