In this lesson, we will create a class to hold the Location information (including a graphic file to display).
NOTE: If you created the projects with .NET Core, you’ll have a problem with the images. They need to be referenced another way. A reader gave these instructions:
If you use .NET core the ImageName property should be “pack://application:,,,/Engine;component/Images/Locations/Home.png”. The images will disappear from the solution explorer when you change their build action to resource, just check your .csproj file and you will see references to them there.
You also have to change your Engine.csproj to be <Project Sdk=”Microsoft.NET.Sdk.WindowsDesktop”> instead of <Project Sdk=”Microsoft.NET.Sdk”> at the top.
Summary
To add an image to your project:
- Create the image in your preferred graphics program.
- Add the file to the project, as an existing item.
- Set the images’ “Build Action” property to “Resource”
- When displaying the file, you will need to include the assembly (project) name where the file is located, along with the path (folders) to the image file.
- For this project, it will be “/Engine;component/Image/Locations/Home.png” (for the Home location image).
Image Files
All image files, in a zip file
Or, download the individual images (right-click, and save to your disk):
Source Code
Location.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Engine.Models
{
public class Location
{
public int XCoordinate { get; set; }
public int YCoordinate { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageName { get; set; }
}
}
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 Location CurrentLocation { 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;
CurrentLocation = new Location();
CurrentLocation.Name = "Home";
CurrentLocation.XCoordinate = 0;
CurrentLocation.YCoordinate = -1;
CurrentLocation.Description = "This is your house";
CurrentLocation.ImageName = "/Engine;component/Images/Locations/Home.png";
}
}
}
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"
FontSize="11pt"
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"/>
<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}"/>
<Button Grid.Row="6" Grid.Column="1" Content="Add XP" Click="ButtonBase_OnClick"></Button>
</Grid>
<Grid Grid.Row="1" Grid.Column="1"
Background="Beige">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="1"
BorderBrush="Gainsboro"
BorderThickness="1">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
HorizontalAlignment="Center"
Text="{Binding CurrentLocation.Name}"/>
<Image Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="125"
Width="125"
Source="{Binding CurrentLocation.ImageName}"/>
<TextBlock Grid.Row="2"
HorizontalAlignment="Center"
Text="{Binding CurrentLocation.Description}"/>
</Grid>
</Border>
</Grid>
<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>
NEXT LESSON: Lesson 04.2: Creating the World
PREVIOUS LESSON: Lesson 03.6: Update Player data with the PropertyChanged event
I’m confused by what you mean when you say in your note “You also have to change your Engine.csproj to be instead of at the top.”
I’m having issues displaying images in .net core solution.
Hi Sam,
It looks like there was a formatting problem when I moved the lessons to this site. If you look at the note on Engine.csproj, you should see the line that need to be changed.
.NET Core changed how images can be displayed. In lesson 14.3, we change how the images are loaded, and that should work for all versions of .NET (.NET Framework, .NET Core, and .NET 5).
I still don’t get why we use Engine;component instead of just Engine. What is the ;component part called? Is this only *and always* necessary when using multiple projects?
We need to include “;component” because that’s how the C# language designers decided to make this work.
You can read more about it here: https://docs.microsoft.com/en-us/dotnet/desktop/wpf/app-development/pack-uris-in-wpf?view=netframeworkdesktop-4.8, where is says:
;component: specifies that the assembly being referred to is referenced from the local assembly. (basically, that the resource file is embedded inside the same DLL/project where we have that Pack URI line)