Download
WindowsFormsDemo.rar [47.5kb] – XNA GSE 1.0 Refresh Project w/ Binaries
Description
Only works with XNA GSE 1.0 Refresh, not in 2.0! See this post.
Here’s a sample demonstrating what I explained in an earlier blog post, but with quite a few updates and precisions.
Here’s what I deduced after working three evenings on this sample :
- Only docked controls work, which means you need to create or use docked containers for all the controls you want to append (except the render panel which must not be docked, but anchored).
- Only mouse input works, like Leaf pointed out on my other post, and as I have tested afterwards. Text input is eaten by XNA.
- The XNA guys clearly didn’t want us to do that, so it’s not “the right way”. There’s a myriad of problems that can happen. I had to work-around on many aspects, like the auto-sizing of the form based on the presentation parameters’ backbuffer size and the background that’s never repainted… And it’s definitely not perfect.
- It’s still the simplest way, and it works well enough for me. I can’t imagine re-writing the whole back-end of the
Microsoft.Xna.Framework.Game
assembly.
Hope it helps!
Hi,
I have little suggestions about your approach to use XNA within windows forms.
1) You can design the form in his original file and access the panel which XNA will render by a property. This avoid to have to copy and paste the forms code.
2) Instead of change XNA DeviceWindowHandle, you can also work together with another window and put this windows as child of XNA form with AddOwnedForm method. This avoid the input problem´s.
Gerosa
@Gerosa: As far as I can tell, you suggestion #2 would have the unwanted side effect that you can still switch input focus between the outer form and the embedded XNA window.
@Zaknafein: I tried this very same approach when I needed to embed XNA in a Windows.Forms window at first, but the GameWindow class used by the XNA GraphicsDeviceManager kept hogging the Application.Idle message by looping until another message enters the queue, which made it impossible to have more than one Game class active at the same time.
I don’t know whether you’ve found a workaround for this, but at least that was the problem that led me to the decision to clone the entire GraphicsDeviceManager and rewrite the idle loop for my game’s world editor…
@Gerosa: Suggestion #1 sounds good, I’ll give it a try!
@Cygon: And why would you want more than one Game class active at the same time? I didn’t have any problem with events (yet).
@renaud.bedard: Each view in an editor requires its own graphics device, thus, its own instance of a Game class (or GameControl in my implementation).
My editor for example is an MDI application where you can have multiple ‘documents’ (game worlds) open at the same time. What happened when I used your approach was that the first MDI child to open always /wins/ — its Game class starts the idle loop (there’s an actual loop that continues until another message is put in the queue) and blocks all other windows from receiving the WM_IDLE message.
Getting this error on build:
Error 1 Cannot find importer “FontDescriptionImporter”. C:Documents and SettingsjsimonMy DocumentsVisual Studio 2005CSharpXNAWindowsFormsDemoWindowsFormsDemoTahoma.spritefont WindowsFormsDemo
Any ideas?
@Jeff : Do you have XNA GSE 1.0 Refresh? I think the Sprite Fonts are new in Refresh.
Looks like that was the problem renaud. Installed the 1.0 Refresh and things are working off of build. Thanks.
This is a beautiful approach to the problem because of the way it preserves the game object. This makes bringing already developed GameComponent’s from your game to your editor much easier, however I would like to see Gerosa’s suggestion reflected, though I’m not entirely sure I understand the method he would take.
It seems too cumbersome to have to copy designer/form code from a template. Any chance of an update? Again, great example.
Hi Heath,
I suggested to let modified code of Form´s InitializeComponent in Xna component´s Initialize, and access the controls by public attributes.
form = new TemplateForm();
windowsGameForm.SuspendLayout();
windowsGameForm.Controls.Add(form.buttonsGroup);
windowsGameForm.Controls.Add(form.statusBar);
windowsGameForm.Controls.Add(form.renderPanel);
windowsGameForm.Controls.Add(form.toolBar);
windowsGameForm.Controls.Add(form.menuBar);
windowsGameForm.MainMenuStrip = form.menuBar;
windowsGameForm.Name = “TemplateForm”;
windowsGameForm.Text = “How To (Properly) Use Windows Forms With XNA”;
windowsGameForm.ResumeLayout(false);
windowsGameForm.PerformLayout();
Hi, I know it’s a dumb question, but i’m new in C# and I have some doubts.
I want to click on a form button and draw something on the XNA render panel…in my case I have a 3D model and I want it to change position when I click the buttons.
How can I do that?
Found-it…nevermind! Hehehe
hi there,
I used this template, insertin a 3d model with rotation on only one axe, and I saw inverted normals problem. Have someone had same problem?
thankyou