WinForms
Quick Resources
- Guide: Getting Started
- Guide: Porting Winforms Applications to Mono
- Guide: Debugging Winforms Applications with Visual Studio
- Tutorial: Using Winforms with Mono/C#
- Frequently Asked Questions about WinForms
- Current Bugs
- Some Winforms Samples
Code Status
Support for Windows Forms 2.0 is complete. At this point, we are largely just fixing bugs and polishing our code.
About System.Windows.Forms
System.Windows.Forms (aka Managed.Windows.Forms, MWF, Winforms) is one of the many GUI Toolkits for use with Mono and is compatible with Microsoft’s System.Windows.Forms. Support for Winforms 1.1 and 2.0 has been completed, and is now in a maintenance/bug fixing state.
System.Windows.Forms in Mono is implemented using System.Drawing. All controls are natively drawn through System.Drawing. System.Windows.Forms implements its own driver interface to communicate with the host OS windowing system. Currently, we have drivers for X11, Win32, and macOS. These drivers translate the native window messages into WndProc compatible messages, to provide as much compatibility with native .Net as possible.
In terms of integrating visually with the desktop, we currently ship with a classic Win32 theme.
Contributing
Currently, all of the controls are pretty much complete. We are now mainly fixing bugs in our implementation. See Bugs.
If you would like to contribute, you can:
- If you find a bug in one of our methods, you can file a bug with a small test case.
- You can fix a bug in one of our methods, either that you found or from our bugs page.
Please note there are a few rules for contributing to Winforms:
- The general rules from Contributing, especially the Special Notes at the bottom.
- Controls must be drawn using System.Drawing code.
- Drawing code must be tied into the theming interface.
- If your method can be tested by an automated NUnit test, please include a test as well.
If you are working on a large feature, you may wish to post your intent on GitHub to prevent duplication of effort.
Drivers
There is a per-windowing system driver which performs the following tasks:
- Keyboard input
- Window creation
- Event translation
Mono’s Windows.Forms implementation translates the native system events such as X11 into Win32 WM_ messages and dispatches them using the WndProc mechanism. This allows applications that depend on overriding WndProc to get some features not exposed by the APIs to still run.
Accessibility
Currently Windows.Forms does not support accessibility, this is being worked on in a separate project that started in January of 2008. See the Accessibility page for details about how this will integrate into the system.
Sample Code
Sample applications for Mono’s Windows.Forms are available in winforms on github
Theming
This section discusses the theming issues in Mono’s implementation of Windows Forms as these questions are asked frequently:
Why Not Use Native Widgets?
It is not feasible to use native widgets on all operating systems. Each OS/Windowing system has different behavior/properties/features for what on the surface looks like the same widget. A RadioButton in Gnome is different from a RadioButton in Win32, which is different from a RadioButton in macOS. To use the native widgets means to reduce the functionality of MWF to the least common denominator of all supported operating systems. If we were designing our own GUI toolkit, this might even be acceptable, however we are implementing an already defined API with defined behavior (and even with application relied-upon side-effects). A RadioButton has to behave exactly like it behaves on Win32 with MS.Net, or else applications written for it may not work properly anymore. And that’s the whole point of Winforms: to allow existing .Net SWF apps to run on Mono. For other uses, there are other choices that may be more appropriate, such as Gtk#.
Fitting In
Although we cannot use native widgets, we still would like to make a reasonable effort to achieve a more native “look and feel” on different platforms. To accomplish this, we have created a theming interface with the hope that in the future it will facilitate our controls looking more native. Having a separate theme class from the get-go forces those who are writing the controls to design code where the drawing code is not integrated and intermingled with the control code.
Maturity of the Theming Interface
Currently, we have the default managed Win32 Classic theme and a native Windows VisualStyles theme. We would like to have native theming on Linux and macOS.
The best option we currently have for theming is the VisualStyles theme. On Windows, this calls the native Windows API and allows it to draw natively for us. Unfortunately, the System.Windows.Forms.VisualStyles namespace is not currently implemented on Linux or macOS. The best way forward would be to implement this namespace on those platforms. (Alternatively, one could port Wine’s uxtheme.dll and we could ship Clearlooks and Aqua themes that people have done.)
The VisualStyles namespace allows you to focus simply on drawing one element, like a “selected button” instead of having to try to sift through the theming code to find out how it draws a button.
History
There were two previous attempts to implement System.Windows.Forms in Mono. These initial attempts were done on top of other toolkits: first Gtk, then Wine. Each one had its share of problems, causing it to be abandoned.
The Gtk effort had the following problems:
- Mapping one toolkit’s semantics to another was very hard.
- It would be very cumbersome to map all events into WndProc events, the messaging system at the core of Windows.Forms.
- The development effort happened early in the Mono life, with this very sporadic development effort, the code quickly became obsolete or bit-rotted.
- Using this on other systems required a Gtk+ installation on the target system (macOS and embedded devices would have suffered the most).
The Wine effort could have been a successful approach, however there were several technical obstacles:
- Multithreading support. Wine has a specific thread setup that is not compatible with Mono. While this was solvable, it would have required larger patches to Wine.
- Dependencies. To have Mono and Wine interoperate, a glue library was required. This library required to know where Wine was installed to (we had a Wine patch that eased this requirement, but it was not accepted into Wine).
- Moving target. Key functions in Wine changed often enough that with every Wine release we had to start over making our glue code work again, sometimes becoming incompatible with previous Wine versions.
- Wine/Gdi+ interactions: The way System.Drawing had to be made compatible with Wine was extremely inefficient. Wine uses the GDI model (raster painting), while our System.Drawing implementation, built on top of Cairo, uses the GDI+ model (compositing model). Making them both talk was extremely inefficient as every transition from one model to the other required the bitmaps to be copied.
The current approach is to implement all controls fully in managed code, and uses an abstract theme interface to paint the widgets. The default theme interfaces renders the widgets using System.Drawing.
Webbrowser Control
Information about the WebBrowser control can be found on the WebBrowser page.
WinForms Designer
For more information check here.