Programming in C#

12. Graphics

Although Windows Forms apps are good for normal user interfaces, they are not quite as good for graphics including moving graphics or games. You need to use the new WPF App. WPF stands for Windows Presentation Foundation which uses XAML format (eXtensible Application Markup Language) which is a special format similar to XML.

12.1 WPF Window.

Create a new Project of type 'WPF App (.NET Framework)' or 'WPF App (.NET Core)' for C#. NB: C++ are different to C#, so remember to select the right kind

When you create a new WFP Application, a MainWindow.xaml file is created which contains the XAML code for the application window. A window is displayed with the XAML code below.
e.g.

<Window x:Class="WPF_Example.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:WPF_Example"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>

</Grid>
</Window>

 

The lines starting with xmlns define the XML namespace (ns), and for this XAML document. The line titles MainWindow describes the height and width of the window. Additional properties can be added such as MinWidth, MinHeight, Margins, alightment transform. You can add them via the Properties window on the right. Note, that the next tag is labeled Grid, this is the default window control for displaying rows and columns . For graphics, you should replace this with the Canvas control which allows you to place other controls such as graphic elements with in the window via specified co-ordinates.
e.g.

<Canvas HorizontalAlignment="Left" Height="450" VerticalAlignment="Top" Width="800">

</Canvas>

12.1 Adding Controls to WPF Window

You can add controls to the WPF Window by drag and dropping them from the toolbox or insert them in the code below. For example, you can add a button control in the Grid or Canvas area:

<Button Content="Play Sound" Canvas.Left="81" Canvas.Top="143" Width="75" Name="PlayButton" Click="playSound_Click"/>

The Content is the same as the Text properties and enters text in the center of the button, the Canvas.Left and top properties specify the relative x,y position of the control within the canxas areas.
The Width is the width of the control, the Name is the name of the control which can be used to reference the control in your code and the Click properties specifies the name of the function to call, if the button is clicked upon. The function should have two parameters: a sender object and an EventsArg parameter.

12.2 Canvas Graphics Controls

Within the canvas area, you can place your graphics. They can be from the normal System.Windows.Controls, or from other classes such as System.Windows.Shapes where you can draw rectangles, ellipses,
lines,paths and polygons. Another useful class is System.Windows.Media which contains brushes, images, color, geometry, fonts, tiling, paths and so on. Other classes include Media3D and Animation.

This example draws a chess board using Rectangle shapes and adds them the the chessboard canvas (defined in MainWindows.xaml):

  

private void drawBoard()
{
Int32 row, col;
System.Windows.Shapes.Rectangle rect;
Boolean bw = true;

// Add rectandles to board
for (row = 0; row < 8; row++)
{
for (col = 0; col < 8; col++)
{
board[row, col] = true;
// Create a rectangle
rect = new System.Windows.Shapes.Rectangle();
rect.Width = size;
rect.Height = size;
rect.Fill = bw ? System.Windows.Media.Brushes.White : System.Windows.Media.Brushes.Black;
// Add rectangle and position it on Canvas.
chessBoard.Children.Add(rect);
Canvas.SetTop(rect, row * size);
Canvas.SetLeft(rect, col * size);
bw = !bw; // Alternate colors
}
bw = (row % 2!= 0);
}
}

13.3 Loading graphics


When loading graphics you should use relative rather than specific paths as the location of the program and its files can be different from when you are developing the project. You can use the relative location of the program assembly files and use that as a basis to look for files. You can then add any subdirectories to the path and then pick up file(s) from that location.
e.g.

string currDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string parentDir = System.IO.Path.Combine(currDir, @"..\..");
string[] files = Directory.GetFiles(parentDir, "image.png");

For example, if the the program file was in C:\Program files\GameProgram\bin\Release, and the image.png file was two folders above, then the final path would work out to be C:\Program files\GameProgram\image.png in files[0] variable.

13.4 Applying graphic file to a control

This is the code to addd a bitmap image from a file and add it to a ImageBish.

System.Windows.Controls.Image knightImage;
System.Windows.Media.Brush knBrush;

private void loadImages()
{

// Get path from program location and load bitmap image from file.
string currDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
string parentDir = System.IO.Path.Combine(currDir, @"..\..");
string[] files = Directory.GetFiles(parentDir, "Knight-40.png");
Console.WriteLine("Path = " + files[0]);
string knightImageFile = (files[0]);
BitmapImage knBmp;

Console.WriteLine("Loading bitmap");
// Create image
knightImage = new System.Windows.Controls.Image();
knightImage.Width = size;

// Set bitmap source
knBmp = new BitmapImage();
knBmp.BeginInit();
knBmp.UriSource = new Uri(knightImageFile);
knBmp.DecodePixelWidth = size;
knBmp.EndInit();

// Define image source
Console.WriteLine("Defining image source");
knightImage.Source = knBmp;

}