Press "Enter" to skip to content

Lesson 03.5: Displaying the Player Object

In this lesson, we will connect the View (MainWindow.xaml) to the ViewModel (GameSession.cs), and display properties from the model (Player.cs).

Summary

In this lesson:

  • To let the “WPFUI” project see classes in the “Engine” project, we need to “add a reference” to the “Engine” project.
    • In the WPFUI project, right-click on the “References” and select “Add Reference‚Ķ”
    • We want to add a reference to the “Engine” project, inside the solution, so we highlight “Projects” -> “Solution” and see a list of the available projects in the solution.
    • Check the “Engine” project, and the “OK” button.
    • Now, the WPFUI project has a reference to (can see the classes in) the Engine project.
  • We defined the layout of the screen in MainWindow.xaml.
    • The XAML file has a related file, where we can put C# code.
      • This is sometimes called the “code-behind” page.
      • xaml.cs is the code-behind page for MainWindow.xaml.
    • xaml.cs is another “class” – just like Player.cs, but it is for creating a screen, not a Player.
      • It has a “constructor”. This is what runs when you create a MainWindow object.
      • The constructor in MainWindow.xaml.cs runs the function “InitializeComponent()”. We will talk about functions later, but this is what draws the screen, and the objects on it (the grid, and labels).
      • We will create our Player object inside the MainWindow constructor.
    • Inside the constructor’s curly braces {}, we will instantiate a GameSession object.
      • This object will be the “DataContext” for the view – the object that will be used in the UI.

Source Code

GameSession.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Engine.Models;
namespace Engine.ViewModels
{
    public class GameSession
    {
        public Player CurrentPlayer { get; set; }
        public GameSession()
        {
            CurrentPlayer = new Player();
            CurrentPlayer.Name = "Scott";
            CurrentPlayer.CharacterClass = "Fighter";
            CurrentPlayer.HitPoints = 10;
            CurrentPlayer.Gold = 1000000;
            CurrentPlayer.ExperiencePoints = 0;
            CurrentPlayer.Level = 1;
        }
    }
}
MainWindow.xaml
<Window x:Class="WPFUI.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:WPFUI"
        mc:Ignorable="d"
        Title="Scott's Awesome Game" Height="768" Width="1024">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="225"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="Menu" Background="AliceBlue"/>
        <Grid Grid.Row="1" Grid.Column="0" Background="Aquamarine">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            
            <Label Grid.Row="0" Grid.Column="0" Content="Name:"/>
            <Label Grid.Row="0" Grid.Column="1" Content="{Binding CurrentPlayer.Name}"/>
            <Label Grid.Row="1" Grid.Column="0" Content="Class:"/>
            <Label Grid.Row="1" Grid.Column="1" Content="{Binding CurrentPlayer.CharacterClass}"/>
            <Label Grid.Row="2" Grid.Column="0" Content="Hit points:"/>
            <Label Grid.Row="2" Grid.Column="1" Content="{Binding CurrentPlayer.HitPoints}"/>
            <Label Grid.Row="3" Grid.Column="0" Content="Gold:"/>
            <Label Grid.Row="3" Grid.Column="1" Content="{Binding CurrentPlayer.Gold}"/>
            <Label Grid.Row="4" Grid.Column="0" Content="XP:"/>
            <Label Grid.Row="4" Grid.Column="1" Content="{Binding CurrentPlayer.ExperiencePoints}"/>
            <Label Grid.Row="5" Grid.Column="0" Content="Level:"/>
            <Label Grid.Row="5" Grid.Column="1" Content="{Binding CurrentPlayer.Level}"/>
        </Grid>
        <Label Grid.Row="1" Grid.Column="1" Content="Game Data" Background="Beige"/>
        <Label Grid.Row="2" Grid.Column="0" Content="Inventory/Quests" Background="BurlyWood"/>
        <Label Grid.Row="2" Grid.Column="1" Content="Combat/Movement Controls" Background="Lavender"/>
    </Grid>
</Window>
MainWindow.xaml.cs
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;
using Engine.ViewModels;
namespace WPFUI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private GameSession _gameSession;
        public MainWindow()
        {
            InitializeComponent();
            _gameSession = new GameSession();
            DataContext = _gameSession;
        }
    }
}

NEXT LESSON: Lesson 03.6: Update Player data with the PropertyChanged event

PREVIOUS LESSON: Lesson 03.4: Creating the GameSession (ViewModel) Class

6 Comments

  1. Leslie P
    Leslie P 2022-07-01

    I’m using Visual Studio 17.2.5 and it does not show the same nodes in the Solution Explorer as your video does; there’s no ‘references’ node at all. I right clicked on ‘dependencies’ and was able to add a reference, but even after doing that, I did not see all the nodes you did once you added the reference. There have been a few other differences, not sure if I installed something wrong or if VS has just been reorganized/designed since you made that video. If the latter, this particular section of your tutorial may need a re-work due to the vast differences in layout/organization of the new VS community ed.

    • SOSCSRPG
      SOSCSRPG 2022-07-05

      Hi Leslie,

      Thanks! I’ll look into updating this. It may take a while, since I’ll need to manually re-run through the lessons before it, to get code in the same condition (unless I can figure a simpler way).

      When Microsoft released .NET Core and .NET 5/6, they made lots of updates to Visual Studio.

  2. Frederico Volpini
    Frederico Volpini 2022-07-26

    Hey!

    I didn’t understand what you did inside MainWindos.xaml.cs
    Is there a place or keyword you can recommend I search about?

    • SOSCSRPG
      SOSCSRPG 2022-07-27

      Hello Frederico!

      I’ll give a general explanation, but please tell me if you have a specific question about something.

      MainWindow.xaml is used to display things in the screen. MainWindow.xaml.cs is used to create or change the objects of the program that are displayed in MainWindow.xaml. The xaml.cs file is sometimes called a “code behind” page for the xaml file, because it holds the logic (code) for the objects that are displayed in the xaml page.

      In this case, we are creating a GameSession object. In the GameSession object’s constructor (lines 14-23), we create (instantiate) a Player object and set its property values. We put that Player object into the GameSession object’s CurrentPlayer property. We put that GameSession object into the xaml.cs page’s DataContext. Every xaml page has a DataContext – the property where it holds the object being used in the xaml.

      If we created a xaml page to edit a Player, we could instantiate a Player object and set that xaml page’s DataContext to the Player object, because the Player object is what we are going to display, and edit, on the xaml page.

      In this code, we have the extra GameSession object because it is going to hold more that just the CurrentPlayer object. We’re going to add location and monster information (objects) into the GameSession class, so we can display that on the xaml page in the future.

      Please let me know if that was not clear, or if you still have questions.

      • Frederico Volpini
        Frederico Volpini 2022-07-29

        You did perfect now, thanks! For both explaining and answering fast.
        Finished the lesson and I both understand and all is working.

        I suppose I don’t need to dive deeper into what the line:

        “DataContext = _gameSession;”

        at MainWindow.xaml.cs does, do I?

        • SOSCSRPG
          SOSCSRPG 2022-07-30

          You’re welcome.

          If you understand that DataContext is a property on Window objects, and we are putting our GameSession into that property, that’s probably all you need to know for now. There are more-advanced things you can learn about DataContext in the future, if you want.

Leave a Reply

Your email address will not be published.