In this lesson, we will create a class to hold the Location information (including a graphic file to display).
Summary
NOTE: If you created the projects with .NET Core, there will be a problem with the images. They need to be referenced a different way. A reader gave these instructions: 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.
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).
Hi Sam, just click directly on Engine in the Solution Explorer. Some code will pop up (which I believe is XML rather than XAML) which at the top should say in angular brackets: Project Sdk=”Microsoft.NET.Sdk”. Just amend .WindowsDesktop at the end so it reads:
Project Sdk=”Microsoft.NET.Sdk.WindowsDesktop”
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)
Hey Scott,
whenever i change the images to a resource they dissapear. i tried doing what was in the note too, but they still went missing. here is what i have so far:: LINK REMOVED FOR PRIVACY
Hi Joshua,
Since your project is in .NET 5, the images will have a problem until we change the way images are displayed in Less 14.3. Unfortunately, that’s something that broke between .NET Framework and .NET Core/5/6.
ok so in 14.3 theres a fix? cool!
Yes. I think the version in that lesson works in all forms .NET (Framework, Core, 5/6)
Hello Scott,
Great Tutorials. I benefit a lot from watching them, following and experimenting based on what you implement.
Unfortunately (same as what Joshua posted) I also encounter a a problem when I change the images to Resource, they disappear in the Solution Explorer Window. OK, I can display them again by clicking on “Show All Files”. I can right-click the Images folder and choose “Include in Project”, which makes them visible again.
But what matters really is that the images do not display when I run the program (hit F5). Nope. Just blank space in the place where the image should be. I have overcome this problem by providing links to the images on the web. Then they do display.
Still, I’d like to fix it that the images from the hard drive are displayed. Any idea how that can be fixed?
FYI I’ve searched the web for a solution and all I found was posts saying to change it back to “Content” or to “Embeded Resource”. That didn’t fix the problem thou.
Still, great Tutorials!
What you included at the top of this page, which I have noticed after a long time, is actually extremely helpful and this solved the “disappearing images” problem.
This part is key: “change your Engine.csproj to be instead of at the top.”
That’s good to hear. I’ll try to make the note more obvious.
Hello. Your tutorial is great! Thank you for that.
In my project the image does not be shown.
I cannot get the image from the other project (Engine) with this code:
CurrentLocation.ImageName = “/Engine;component/Images/Locations/Home.png”;
So i tried to make the same Folders in WPFUI and added the images also there.
Then i try:
CurrentLocation.ImageName = “/WPFUI;component/Images/Locations/TownGate.png”;
and it works fine.
Therefore i think there is a problem with the reference, but i cannot find it.
Is it because of the newer .Net Version (you made the corse years ago 🙂 )
I hope you can help me, i love your tutorial and really want to follow the whole corse.
Greetings from Austria.
You’re welcome, Michael,
Yes, the code for the images originally worked with .NET Framework, and doesn’t work with .NET Core or .NET 5/6. However, in Lesson 14.3, we change the code for the images to something that works for all versions.
Take care! (from Texas 🙂 )
The resource packing isn’t working for me either. I just called a direct link to a manual location and will package the files manually with the binary.