WPF controls can be added to any FlatRedBall PC game. This walkthrough shows how to add a floating control which will both display runtime information and also be used to add new entity instances.
This tutorial uses a Glue project named "FrbAndWpf" as the starting point. This Glue project will contain the following:
An entity called "CircleEntity"
CircleEntity will contain a single Circle named CircleInstance
A screen called GameScreen
GameScreen will contain a PositionedObjectList of CircleEntities named CircleEntityList
By default the game will not display anything since the CircleEntityList will be empty.
Before adding any code or XAML to the project you'll need to add a few library references. To do this:
Open your project in Visual Studio
Right-click on "References" under your project
Select "Add Reference..."
In the dialog that appears select the "Assemblies" option
Check the following assemblies:
PresentationCore
PresentationFramework
System.Xaml
Click OK
To create a window:
Right-click on your project
Select "Add" -> "New Folder"
Name the folder "Wpf"
Right-click on the newly-created folder
Select "Add" -> "New Item..."
Select "User Control (WPF)"
Enter the name "DiagnosticWindow"
Click "Add"
For this tutorial we actually want DiagnosticWindow to be a Window and not a UserControl. We can change this by opening up the XAML for this and changing "UserControl" to "Window". The XAML should look like this:
The inheritance code in the codebehind needs to be modified to inherit Window as well. Modify the codebehind to look like this:
Now that we have a Window called DiagnosticWindow we can instantiate and show it in Game1.cs. To do this:
Open Game1.cs in Visual Studio
Find the Initialize method
Modify the Initialize function to instantiate and show the DiagnosticWindow so it looks like:
Also the use of WPF requires that the Main function has the STAThread attribute. To add this:
Open Program.cs
Add the STAThread to the Main method so it looks like:
The DiagnosticWindow will have two elements:
A Label that will display how many PositionedObjects are in the engine
A button used to create entities
Modify the DiagnosticWindow XAML so it is as follows:
Note: WPF is typically implemented with binding and MVVM. For brevity we won't use these patterns in this tutorial, but you should consider doing so as you expand your FRB/WPF application.
Of course you'll need to add a Button_Click event to the DiagnosticWindow codebehind:
First we'll add logic for the button to be able to create entities when clicked. First we'll tell Glue to create a factory for us:
Switch to Glue
Select CreatedByOtherEntities to True
Next we'll use the factory to instantiate a CircleEntity whenever the button is clicked. To do this:
Switch to Visual Studio
Navigate to the Button_Click method in the DiagnosticWindow
Modify Button_Click so it looks like:
For a more complicated game we might update the label on a timer, or by using a view model. In this case we'll simply update the label whenever the user clicks the button. We can do this by modifying the Button_Click method so it looks like:
Now clicking the button will instantiate an Entity and update the label to show how many objects are in the engine:
For information on this problem, see this post.
This tutorial showed how to add a WPF window to an existing FlatRedBall (Glue) project. It shows how to both display information as well as drive behavior using the UI. Of course, it implements the bare minimum for a working example but WPF can be added to games to create very powerful diagnostics and behavior.
At this point you'll want to make sure to save your project. You can do this by build/running it, or by using the "File" -> "Save All" menu item. Running the game shows the WPF window next to the FRB window:
If you run the game now and click the button you'll see that you can create entities: