MonoGame.Forms - Create your Editor Environment!

Ok fine. Please try the following:

Place this code block:

protected override void OnMouseWheel(MouseEventArgs e)

in the MapHost class and place a breakpoint inside this method.

See if it can reach this breakpoint.

I added that in and placed a breakpoint, but it still doesn’t seem to be working. Very weird.

It’s possible that the controls may not have input focus.

Let’s try this:

Put this code block additionally:

protected override void OnMouseEnter(EventArgs e)

        if (!Focused) Focus();

protected override void OnMouseLeave(EventArgs e)

        if (Focused) Parent.Focus();

in the MapHost class and test these events as well as the mouse wheel events from the previous posts.

That did it! Upon adding those, it hits the breakpoint I added in OnMouseWheel.

Thank you so much! :slight_smile:

This is great :slight_smile: I’m glad I could help.

Can you confirm that the breakpoints in OnMouseWheelUpwards and OnMouseWheelDownwards are working too now?

Yeah, both of those are working now as well.

1 Like

Okay nice.

I already applied a patch on the dev branch (not public). It will be available on the master branch in the next iteration of MonoGame.Forms, so you don’t need to fiddle around with OnMouseEnter and OnMouseLeave in your custom controls.

I will push out along other improvements soon.

Thanks for reporting the issue @mgtaa!

MonoGame.Forms - MouseWheel Event Fixes and DebugPanel

  • Added the public Texture Pixel and the public Color DisplayBackColor to draw a panel behind the text of the integrated display and make them useable by the end user.
    Also rewrote the drawing logic of the integrated display accordingly.
  • Fixed that the MouseWheel events didn’t fire for some users, because custom controls didn’t get Focus() when the mouse cursor entered a custom control.
  • Set the cached float FontHeight in GFXService to public as it is also useful in custom controls, when working with the integrated display font.
  • Relative and absolute MousePositions switched from Microsoft.Xna.Framework.Vector2 to System.Drawing.Point, as it’s more fluent in a WindowsForms environment.
  • Added protected bool IsMouseInsideControl to the GraphicsDeviceControl, so that it’s easily possible to check if the mouse cursor is inside a (resized) control.

NuGet: NuGet Gallery | MonoGame.Forms

Better readable debug panel:


MonoGame.Forms - Removed IGFXInterface and added global MousePositions

  • Access modifier of UpdateFrameCounter() and UpdateDisplay() are now internal.
  • Removed IGFXInterface as it’s not needed anymore.
  • Added internal void UpdateMousePositions to the GraphicsDeviceControl and calling it in the DrawWindow and UpdateWindow (GameControl) to make them available in all custom controls through the Editor service classes.
    • This makes it possible to use the relative- and absolute mouse positions in the DrawWindow (updated through invalidation).


MonoGame.Forms - BackBuffer Fixes

  • The BackBufferWidth and BackBufferHeight (PresentationParameters) are now equally set on all custom controls.

This fixes a bug where resizing a control also resizes the BackBuffer- Width and Height for other controls (because they weren’t updated accordingly).


1 Like

Hi, I’m very interested in this, as I’m making a GameBoy emulator and I’m going to use MonoGame for the rendering and sound, and WinForms for the UI controls and GameBoy debugger.

Someone said WinForms uses GDI+ and therefore MonoGame will be slow. Is this true? I really have no idea about MonoGame nor WinForms so I can’t answer this question myself.


Even when embedded in WinForms, MonoGame will use DirectX or OpenGL for rendering, so MG will not run slower than usual.

This may sound like a “dumb” question but could someone explain exactly what MonoGame-Forms is.

Is this a way to add a complete GUI to your MonoGame Project?

Thank you…


No, this is exactly not the purpose of MonoGame.Forms.

To quote the headline of the readme file:

MonoGame.Forms is the easiest way of integrating a MonoGame render window into your
Windows Forms project. It should make your life much easier, when you
want to create your own editor environment.

So the purpose of MonoGame.Forms is - for example - creating your own editor tool, which needs a rendering window, for your own game.
This could be a level editor or a particle effect editor for example.

You basically create a new WindowsForms project and then add the MonoGame.Forms library to this project, to make the rendering capabillities of the MonoGame.Framework available in your editor project in a very easy way.

Also what @KiloMikeCodesStuff said should be possible. Creating your GameBoy emulator with MonoGame.Forms should be very doable, when you know how to render your contents using the MonoGame.Framework. Everything else is just the usual business of WindowsForms (working with a complete GUI solution for projects like that).

I also reccommend reading the README file and the Wiki (which describes the class library) to get a better overview.

Regarding developing games inside MonoGame.Forms: Yes, it’s kinda possible. The library has native Keyboard and GamePad support of the MonoGame.Framework as well as RenderTarget support. However it only supports the Windows platform and I have never tested things like fullscreen support and different resolutions (but it’s possible to resize the render controls), because - as I said - this is not the purpose of the MonoGame.Forms library.

I recommend using the MonoGame.Forms library for tools and editors only. Not for whole games on a bigger scope.

1 Like

Thank you for your informative reply, sqrMin1… :slight_smile:

So then, if I am ever able to complete my military simulation, I could then use this library to create, for example, a scenario editor. Is this a better understanding of your software?

Yes, you could do that, but it realy depends on your needs.

For example: it’s also possible to create a scenario editor without the need of a rendering window, as long as such an editor only needs to process and handle plain data.

But if you need a graphical / rendered representation of such data (which includes realtime updates), then MonoGame.Forms is there to help you with that.

MonoGame.Forms - MSAA Accessibility

  • The maximum MultiSampleCount (MSAA Antialising) of the users GraphicsDevice is now cached in PresentationParameters.MultiSampleCount, so this information becomes easy to access in custom controls, which is useful when working with custom RenderTargets.
  • It’s now possible to get the clamped MultiSampleCount in custom controls by calling GetClampedMultisampleCount(int).
  • This function always returns the desired MultiSampleCount clamped to the nearest power of two in a descending order (e.g.: input = 7; output = 4).

NuGet: NuGet Gallery | MonoGame.Forms

Easy to work with MultiSampling in MonoGame.Forms:

MonoGame.Forms - MSAA Accessibility (Refreshed)

  • GetClampedMultisampleCount is now internal.
  • Added public void SetMultiSampleCount(int) which calls the new internal event Action<int> UpdateMultiSampleCount, so the wanted MultiSampleCount will be available in all editor service classes.
  • Added internal AntialisingRenderTarget and internal void RefreshAntiAlisingRenderTarget, which automatically updates itself based on ClientSize and WantedMultiSampleCount.
  • GraphicsDeviceService is now internal.
  • as well as the corresponding field in GraphicsDeviceControl.
  • Added the internal int MaxMultiSampleCount and cache the value there instead of in the presentation parameters, to make this value save from manipulation, because it is used by the GetClampedMultisampleCount in GraphicsDeviceControl as a fallback.

Use Antialising (MSAA) in your custom controls like this:

protected override void Initialize()

   SetMultiSampleCount(8); //Usual numbers are 0, 2, 4, 8

protected override void Draw()



   //Your drawings



As you can see, everything between BeginAntialising() and EndAntialising() will be affected by MSAA.

NuGet: NuGet Gallery | MonoGame.Forms

MonoGame.Forms - Antialising Fixes

  • Added missing nuget references to SharpDX.dll, SharpDX.DXGI.dll and SharpDX.Direct3D11.dll.
  • Added public int GetFrameRate to get the current frame rate of a custom control.
  • Changed internal event Action UpdateMultiSampleCount to public so the user can react to multi sample changes in custom controls.
  • The AntialisingRenderTarget now correctly gets disposed on refreshing.
  • Fixed a NullReferenceException when the SwapChainRenderTarget is null.
  • Rethought the disabling of the AntialisingRenderTarget after a ControlResize event. It automatically reactivates itself after 500 milliseconds after a ControlResize event occours.
  • This prevents OutOfMemoryExceptions on recreating the AntialisingRenderTarget as well as NullReferenceExceptions if the current internal Rendertarget is lost, when switching from the AntialisingRenderTarget to the SwapChainRenderTarget.

Dev Note for the next Build (
Planning to implement a RenderTarget Manager where users can add their custom RenderTargets to, so they becoming automatically updated internally (based on the ClientSize for example).

NuGet: NuGet Gallery | MonoGame.Forms


MonoGame.Forms - Render Target Manager

  • Added a RenderTargetManager to fully manage custom RenderTarget2D’s internally - based on ClientSize and MultiSampleCount.
  • Fixed memory leaks on reinitialization of custom controls.
  • Added public event Action RenderTargetsRefreshed so the user can get notified when the RenderTarget2D’s, hold by the RenderTargetManager, got refreshed.
  • Renamed events to make it more clear what they are meaning:
  • UpdateSwapChainRenderTarget -> SwapChainRenderTargetRefreshed
  • UpdateMultiSampleCount -> MultiSampleCountRefreshed
  • Made SwapChainRenderTargetRefreshed internal.
  • Changed some XML comments so they are better understandable.

Using the RenderTargetManager

protected override void Initialize()

    // Adding a new Rendertarget2D with the keyname "MyTarget" to the Manager
        Editor.GetRenderTargetManager.CreateNewRenderTarget2D("MyTarget", false);

public override void Draw()
    // Set the new RenderTarget
    Editor.BeginRenderTarget("MyTarget", clearColor: Color.Transparent);

    // Your Drawings ...

        // Automatically revert to the SwapChainRenderTarget
        Editor.EndRenderTarget("MyTarget", drawToSpriteBatch: false, clearGraphics: false);