MonoGame.Forms - Create your Editor Environment!

Good luck. I’m hesitant to volunteer as the only flicker solution I found was to force the main thread to sleep, that at least reduced resize flickering (from rebuilding the back-buffer) to occur only when the machine was legitimately doing too much work. I got the sample in github working but it was flicker nightmare (edit: the MonoGame sample, not yours).

This is really cool though. I’ve worked with Sony’s ATF before and while it was mostly great … bloody hell does it flicker all of the time. I might be able to put up with it if rendering were less of an issue (oh dear, I went with ‘slaving’ a native SDL window into it before … that was fun).

A rock-solid MonoGame WinForms control would be awesome.

1 Like

MonoGame.Forms v1.4 - Keyboard Functionality

I had time to look at a proper keyboard implementation to push MonoGame.Forms ability of hosting / embedding
a MonoGame game with keyboard controls.

It’s working fine so far:

The Repo is already updated as well as the NuGet.

The sample project from the video to test the controls by yourself is included.

I recently saw / used a working WindowsForms XBOX controller implementation. I think it’s also possible to put that functionality to MonoGame.Forms.

1 Like

I just wanted to say this looks like a really awesome project.

Congrats man! :slight_smile:

1 Like

We need OpenGL support here! :smiley:

1 Like

Just to complete the “controls-section”:

The gamepad worked out of the box (instead of the Keyboard). I recently updated the Repo or rather the AdvancedControlsTest.cs sample, which makes it possible now to control the player sprite with a gamepad.

Now you can use a keyboard or a gamepad inside a MonoGame.Forms render window.

Again thank you all for your comments! :slight_smile:

There’s a trick to enable the Keyboard on WinForms.
http://community.monogame.net/t/work-around-call-non-public-method-custom-game-loop-not-using-game-class-only-partial-info-from-keyboard-getstate/

1 Like

Indeed this is a very nice trick :slight_smile:

I already implemented keyboard functionality in a different way:

  1. In the main form I override ProcessKeyPreview to catch keyboard messages and traverse them to registered controls.

  2. The messages are getting processed in the GraphicsDeviceControl and formatted into the MonoGame specific format through a MappingDictionary if the corresponding control is visible.

  3. You can then read the valid key presses through a custom Keyboard.GetState() method.

I saw this approach a while ago in a blog and main reason for using this was that Control.Focus() for neccessary keyboard input didn’t worked well (sometimes keyboard input worked and sometimes not). However I don’t saw your solution before, but it seems to be much simpler and more elegant :slight_smile: . Thanks for sharing @nkast!

The custom Mouse.Windows.cs in the end of your linked post is also looking helpful for having full mouse support. Currently I just getting the mouse clicks through a simple forms MouseDown event, which works without a problem, because the control automatically gets focus on click (instead of by a key press).

You mean when the control doesn’t have the focus?
I had the same issue with mouse wheel, I wanted to send the Wheel delta to the control bellow the mouse, not to the one that had focus. I found this little gem (CaptureMouseWheelWhenUnfocusedBehavior) at stackoverflow.

It traps all app messages and redirect them to some controls you register. With the right modification you can do the same for KeyUP/KeyDown messages.

@nkast Sorry for the late reply, I was pretty busy. Thanks for sharing the stackoverflow topic and yes, I had problems with the control focus regarding keyboard input; but they are solved.

I did some small tests with regular windows forms mouse events in custom controls with a good success. I was also able to use the mouse wheel in multiple custom controls (render windows) in the same view and without explicit focus.

I will soon report back with an updated repo which has full mouse support.

I will soon report back with an updated repo which has full mouse support.

Good to hear.
FYI, I posted a PR that enables Mouse on any Wnd
control.

Thank you very much, but I can’t find the PR. Can you please check it again?

Here it is: https://github.com/MonoGame/MonoGame/pull/6081

and here’s the MG setup: http://teamcity.monogame.net/repository/download/MonoGame_PackagingWindows/58823:id/MonoGameSetup.exe

You have to set Mouse.WindowHandle to your Control.Handle.

1 Like

Ah, it’s in the MonoGame repo - my bad :slight_smile:

You made some nice commits. Someone in a forms environment could use the native MonoGame mouse state or the basic mouse events from the controls in that way. I like that the user could decide what he wants to use - depending on his needs or developing experience with WindowsForms or MonoGame.

First I will push the recent changes I did together with updated sample projects. After that I will come back to your changes and when I have time I will implement this. In the moment I’m very busy, so updates could take a while.

Thanks for your help @nkast!

Update: Multiple Controls & Mouse Input

In this update I show you multiple controls on one form and different mouse actions happening on those controls.

Please watch in fullscreen and 1080p:

I removed the old mouse button click detections and worked with the native windows forms control events instead. You can use all common mouse buttons now:

  • Left Button
  • Right Button
  • XButton1
  • XButton2
  • Mouse Wheel

In the new sample project (you saw in the video) I created the abstract MapHost.cs class to show you how you could share a common code base on multiple MonoGame.Form controls, but still treat each controll differently. The controls in the view are both inheriting from the same MapHost, but they are getting initialized independently.
This keeps your main control classes clean and easy to manage, because only the non-abstract classes, which inheriting from a MonoGame.Forms control, are visible in the ToolBox from the designer (compare: Control_A vs Control_B)


For the next update I plan to bring back the native MonoGame mouse input using the updates from @nkast. This also has the advantage of faster click detections in relation to the WindowsForms event system.

You can then use both: WindowsForms Mouse Events and MonoGame Mouse Input.

1 Like

MonoGame.Forms 1.5 Released!

  • Removed old Keyboard Util and Service classes

  • Added Mouse input support (now MonoGame native)

  • Added Keyboard input support (now MonoGame native)

  • Raised MonoGame.Framework to 3.7.0.1114 (DirectX)


The mouse handle is now attached when a new control is created, so you could simply use Mouse.GetState() of the MonoGame framework.

I implemented the nice Enable-Keyboard-Trick to enable the native Keyboard.GetState() method of the MonoGame framework.

At this point big thanks to @nkast for your nice input! (pun detected? :smiley: )

It automatically enables itself when the control has focus and disables when it becomes unfocused.
I added the flag “AlwaysEnableKeyboardInput” so you can override the unfocused behavior (sometimes you may want to have either the keyboard for text input or game / editor related input and sometimes you may want to have game / editor input no matter where the mouse cursor currently is or rather which control has the focus).

Also thanks to everyone else here for your nice ideas so far!

Regarding extendend input capabillities of MonoGame.Forms I think we managed to get everything from the MonoGame framework working.

Thanks again :slight_smile:

2 Likes

This is only good on windows right ?

Anyways if that is the case i found this it might be helpful.
http://www.pinvoke.net/default.aspx/user32.mouse_event
and this
https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-and-screen-scaling.

And how does it work for Linux, Mac and Android and other platforms? :open_mouth:

Currently only the windows platform is supported.

I want to add something to the screen scaling:

You should set AutoScaleMode to None on a Form containing a MonoGame.Forms control, otherwise the whole drawn content of the control would be misplaced due to the different viewport size.

If you still want to use DPI scaling, then you need to get the current DPI scale factor of the user and scale all control content by that factor. You can catch this factor in your Form class like this:

System.Drawing.SizeF CurrentDPIScaleFactor = AutoScaleFactor;

If you create a more complex editor environment you could split the DPI scaling of MonoGame.Forms controls and different controls, which containing text and other form controls, by using a DockPanel system and only turn the scaling off for a particular DockContent - containing a MonoGame.Forms control, and then dock it to a DockPanel.

I can reccomend this DockPanelSuit for this purpose. I’m using it in the Rogue Engine Editor and it’s very nice and easy to work with, but for small editor projects it would be a bit overhelming.

MonoGame.Forms 1.5.7.0 Released!

  • It’s now possible to set the GraphicsProfile during Design-Time (see picture below)
  • Editors from DrawWindow and UpdateWindow are now hidden from the property grid
  • Disposing MouseWheel events to prevent memory leaks in the samples project
  • Added missing MonoGame.Framework assemblies to NuGet with automated referencing, when installing the package

GraphicsProfile

2 Likes

MonoGame.Forms 1.6.0.0 - Window Resizing!

  • The SwapChainRenderTarget now gets updated when resizing a Forms window, so that the drawn content won’t get stretched and distorted anymore.
  • DrawService and UpdateService are now both inheriting from IDisposable. Contents of the service classes are now getting disposed automatically.
  • The Camera2D component automatically reacts to the new window resizing feature.

NuGet: https://www.nuget.org/packages/MonoGame.Forms/1.6.0

2 Likes