PAGES

Archives

How To (Properly) Use Windows Forms With XNA

Here’s something I had some difficulty doing “gracefully” with XNA : force a custom render device and user controls in the window while still using the Game framework. It’s quite easy to initialize XNA in a Managed DirectX fashion but you lose the links to the graphics device manager, the content pipeline and a lot of very useful (and well written) code behind the Game class.

I initially tried to mimic the functionality of the Game class with a home-made class, make my own ServiceProvider and everything. But by using Lutz Roeder’s .NET Reflector I found out that Microsoft actually made everything better than I usually did; the elapsed-time management, how to hook the events on the form, the overall structure… So I started reverse-engineering bits of it, then I ended up copying the whole goddamn assembly (because of course most of it is internal and sealed) just to allow me to use my own form as the viewport! Ridiculous. There had to be a better way.

And there is!! In the comments of the above article, a user named chrisf suggested to use Control.FromHandle() on the handle provided by the GameWindow class, and use the resulting Control to add whatever controls inside of it.

I just extended the technique by casting the Control to a Form (the implementation class is WindowsGameForm, an internal class that extends Form) and doing pretty much everything I want on it. The operations are done in a standard GameComponent that represents the form’s controls, and is the host of all the events.

And add a method to add whatever components you want, in this example a MenuStrip and a rendering Panel. The cool thing is that you can do the form editing in a real form, then copy the code from the “designer” partial class underneath it :

Leaf: Thanks for the input (uh, no pun intended), I didn’t know that. It doesn’t really matter to me, but it might to others…

snarg: I don’t think you can overlay controls on the render target… To do that you’d better make your own GUI system directly in the XNA context. I’m sure you’d meet a lot of problems (like focus or grey outlines around the controls) by overlaying standard controls.
Still interested in a sample?

you might need some minor changes in Button.cs at asset names depending on where you image files are located within your ContentRootFolder. Also you mustn’t forget to change the namespace, by default it’s Blue_Ball_2, or you can also put a using statement in your Game1.cs. I hope this helped.