A while back I wrote up a method for rendering XNA Game Studio 4.0 content inside of a WPF window. My method involved using a render target and doing a CPU transfer of those bits into a WriteableBitmap. This method had some pros and cons:
Pros:
Cons:
These limits may be acceptable for some people. I built a real-time shader editing tool using this system and it worked great for my needs. However since some people have asked for more ways to do this integration that provide more performance and don't require the render targets, I went back to the drawing board a bit. After talking with a coworker for a bit (i.e. taking his core idea and running with it ;-) ), I have come up a new solution for this integration using WPF's HwndHost base type.
The idea of the new solution is simple: create a control subclasses WPF's HwndHost to create a child window to which the XNA Framework will render graphics. I leveraged the GraphicsDeviceService from the WinForms sample (with some modifications) to handle GraphicsDevice management and used the CompositionTarget.Rendering event to drive my draw loop. I also used some concepts from the GraphicsDeviceControl in the WinForms sample so that each of my controls will present to the correct window handle, thus enabling apps to have multiple controls running at the same time and sharing the same GraphicsDevice.
This solution, however, is not without its own set of trade offs. Essentially we're flipping the pro/con list from above:
What it comes down to is that these two solutions are both useful in different ways and therefore I recommend you look at them both to see which will meet your needs.
At a high level, use of this new sample is very simple. Add a GraphicsDeviceControl into your XAML layout where you want to render XNA graphics. The GraphicsDeviceControl has a LoadContent event that will fire when the GraphicsDevice has been created and a RenderXna event that fires each frame for you to draw your content. Additionally there are a number of "Hwnd*" events for various aspects of mouse input since I couldn't route it through the normal UIElement mouse events. The control also has methods to capture/release the mouse which makes the cursor invisible and forces the cursor position to reset, which is great for tools where you want to rotate an object and not worry about the mouse leaving the view.
The sample application shows how to leverage these various actions in an app with two GraphicsDeviceControls. The top control draws a constantly spinning cube whose color is based on the sliders in the left panel. The bottom control draws a cube in one of three colors than can be changed with the buttons next to the control (or using the 'R', 'G', or 'B' keyboard keys which are set up as hotkeys for those buttons). Additionally you can use the right mouse button and drag to rotate the bottom cube without capturing the mouse or the left mouse button and drag to rotate the cube with capturing the mouse.
Hopefully this proves useful to some of you. Feel free to leave questions or comments below, but to make this point clear: the implementation of this solution is pretty complex and I cannot provide much support as I simply don't have the time. I encourage everyone to play with it, but if you run into issues please start by checking out MSDN documentation or ask on the App Hub forums so that the community can work with you to solve the issue.
Disclaimer: This code was written by a colleague and myself and is not an official solution for mixing XNA Game Studio and WPF. Use of this sample is at your own risk and I make no guarantees as to the quality or usability of the code. I do not guarantee any level of support for users of this sample. The code in the downloadable sample is licensed under the Microsoft Public License, the terms of which can be found here: http://www.microsoft.com/opensource/licenses.mspx#Ms-PL