System windows forms mono

WinForms

Quick Resources

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.

Читайте также:  Gtx 550 ti windows 10 driver

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.

FAQ: Winforms

My forms are sized improperly

This can be caused by AutoScaling. You can try disabling it:

If this fixes it, you can disable it in your application by removing the following line from your form’s designer code:

(This line is added automatically by Visual Studio when it creates a new Form. However, if your forms look bad on Linux because of this, they will also look bad on any Windows computer where the default font has been changed.)

My multithreaded application crashes or locks up

Mono’s implementation of WinForms does not support Forms or Controls being created on multiple threads. All Forms/Controls must be created on the same thread.

Note this only applies to creation. You can still write multithreaded applications that do work in other threads and modify already created controls using Control.Invoke.

How can I keep the terminal window (“dos prompt”) from showing when my application runs?

You need to compile you application with -target:winexe, like this:

How can I use Visual Styles?

Beginning in Mono 2.2, we have a VisualStyles theme for Windows XP/Vista/7 that uses native Windows rendering.

It is enabled by calling Application.EnableVisualStyles () before calling Application.Run (), just like in .Net.

Visual Styles are not currently supported on Linux/macOS. It is fine to call EnableVisualStyles () on these platforms, it just won’t have any effect.

How can I make my windows alpha blended? (transparent)

Mono’s Winform implementation supports transparency on its windows as long as the underlying windowing system has support for it.

Читайте также:  Не могу установить драйвер звуковой карты windows 10

For Unix/X11 users this means that they must have the COMPOSITE extension enabled on their server, and they must be running a compositing manager, like xcompmgr.

The GenToo Linux Wiki has a good description on how to setup the Xorg server for transparency support.

What are you using to implement Windows.Forms?

Windows.Forms is implemented fully in C# managed code and uses System.Drawing to perform most of its tasks.

For more details see the Winforms Roadmap

A small driver is required for each operating system supported. Currently we have drivers for:

  • X Window System
  • Win32 Window System
  • macOS Window System

Will I be able to run my smart clients on systems powered by Mono?

As long as your applications are 100% .NET and do not make use of P/Invoke to call Win32 functions, your smart client applications will run on Mono platforms.

Does Winforms run on macOS?

Yes, as of Mono 1.9, Winforms has a native macOS driver that it uses by default.

Do you have a comparison chart about the various toolkit offerings?

GDIPlus Initializer Exception

If you get the following error:

This means that you do not have installed libgdiplus in your system, make sure that libgdiplus is installed and that the library can be found.

You might want to use this command line to debug this problem:

Missing Method Exception

If you get the following error:

This means that you are attempting to use a method that has not been implemented yet in Mono (and you compiled with Microsoft’s compiler or you would have gotten an error at compile time).

You have three options:

  • Adjust your code to not use this method.
  • Implement the method in Mono.
  • Wait for it to be implemented in Mono.

To see which methods are currently missing from the git version of Mono, see the class status pages.

WinForms Application in MonoDevelop

I just installed the new MonoDevelop Windows beta, but when trying to create a C# windows application the only option was GTK#. Since Mono supports WinForms, why is this not an option in MonoDevelop. I would like to not have the GTK# dependency in my applications.

3 Answers 3

Althought Winforms is supported in mono since version 2.0, the WinForms designer is not usable yet in MonoDevelop, which could be the reason for the lack of a WinForms project in MonoDevelop

AFAIK, you should think of mono’s support for winforms as a way to port existing winforms aplication to linux. If you want to make a cross-platform app from the ground up, you should use GTK#

Although there is no WinForms project template, you can write WinForms apps in MD on any of the platforms MD runs on.

Just create a new empty C# project and add a reference to System.Windows.Forms, then write your code, and build & run. Although there’s no Winforms designer in MD, you’ll have code completion for the Winforms types.

Sorry for raising the dead, but I tried to do this recently. While MonoDevelop doesn’t provide the GUI designer, you can indeed write Winforms by hand, as mhutch pointed out. It goes like this:

  • Create a new, empty C# project.
  • Add a reference to System.Windows.Forms
  • Create a new, empty C# file:

The contents of the file:

Expand your Form by adding components to MainForm’s constructor.

Mono и Windows Forms на Nokia N900? Да не вопрос!

Я был несколько удивлён, не увидев mono в репозиториях для этого замечательного устройства. Но, поскольку оно было позарез нужно, решил всё-таки собрать. И тут же напоролся на весьма забавную особенность маэмовского SDK, которая этого сделать мне не позволила. Но обо всём по-порядку. А пока что небольшой скрин того, что получилось:

Вместо нормального эмулятора устройства и тулчейна для сборки, ребята из нокии приспособили под это дело scratchbox, который, эксплуатируя qemu-user, запускает arm-ные бинарники прямо на ядре текущей ОС. И всё бы замечательно, если бы оно работало как надо. На деле же во время сборки qemu выдаёт «unsupported syscall 242», после чего сборка стопорится. Обычным кросскомпилером тут что-либо сделать сложно, ибо mono в лучших традициях процедуры bootstrap (поднятие самого себя за шнурки ботинок) компилит сначала свой компилер и уже с его участием дособирает всё остальное. Как с этим бороться, не особо понятно, если только компилить на девайсе, но там это займёт годы. Для N800 mono какой-то герой таки смог собрать, но работать на n900 оно отказалось, вываливаясь с SIGSEGV. Если кому-то интересно, как сия проблема была решена, или же самостоятельно пощупать моно на устройстве (можно прямо в Visual Studio писать, если что) прошу под кат.

Читайте также:  Windows 10 education edition download

Для начала опишу, как сделать не получилось. Тем не менее, при этом был получен экспириенс и информация может быть весьма полезна.
Про SDK писать не буду, про его установку и настройку и без меня много написано.

Блин первый. Компилим на девайсе.

deb http_s_://downloads.maemo.nokia.com/fremantle/ssu/apps/ ./
deb http_s_://downloads.maemo.nokia.com/fremantle/ssu/002 ./
deb http_s_://downloads.maemo.nokia.com/fremantle1.2/ovi/ ./

deb http_://repository.maemo.org/extras/ fremantle-1.3 free non-free
deb http_://repository.maemo.org/extras-testing/ fremantle-1.3 free non-free
deb http_://repository.maemo.org/extras-devel/ fremantle-1.3 free non-free

deb http_://repository.maemo.org/ fremantle/sdk free non-free
deb http_://repository.maemo.org/ fremantle/tools free non-free

_ из ссылок убираем, он там по той простой причине, что парсер — лох, и не понимает даже тега code.

  • Ставим build-essential, bison, gettext, m4
  • ./configure && make && make install
  • Осознаём, что процесс займёт десятилетия и ищем иные пути
  • Блин второй. Компилим на эмуляторе.

    Для начала нам потребуется вытащить саму необрезанную rootfs. Тут есть 2 пути. Во-первых вы можете распаковать прошивку флешером (flasher-3.5 -u -F ОБРАЗ) и смонтировать rootfs.jffs. На самом деле там не jffs, а ubifs, кстати. У меня получилось вот по этому мануалу.

    Ещё можно подгрузить систему восстановления, как описано здесь. Там сей образ используют дабы подвинуть разделы, но нам это не надо. После чего во внутренней консольке делаем mount -t ubifs ubi:rootfs /mnt и сливаем всё на флешку. Хороший метод бекапа, кстати, настоятельно рекомендую.

    Далее по мануалу делаем себе образ убунты для qemu.

    Дабы облегчить себе жизнь и получить возможность chroot’иться в arm-ое окружение нужен будет пакет qemu-kvm-extras-static. Копируем после установки /usr/bin/qemu-arm-static в /bin своей системы и chroot магическим образом начинает работать. Если кому интересно, как это происходит, могут почитать про binfmt_misc и прочие вкусности, которые нам позволяет linux. Теоретически так можно на самом девайсе ubuntu x86 в chroot-окружении запустить, а в ней завести wine. Хотя, скорее всего не получится, ибо наткнёмся на всё те же неподдерживаемые системные вызовы.

    Монтируемся, создаём директорию maemo, разворачиваем образ, который сдампили, далее всё по первому блину.

    В итоге во время компиляции mcs начал вылетать с internal error и ничего я с этим поделать не мог. Тем не менее была получена среда сборки независимая от бажного scratchbox-а (который ко всему прочему ещё и только под i386).

    Наконец-то успех!

    На третий день Зоркий Глаз заметил, что у сарая нет стены. А именно: практически весь mono — это управляемые dll-ки, которым решительно всё-равно под какой платформой их запускают. В результате созрел следующий план:

    1. Через apt-src install вытаскиваем сырцы моно. При этом они уже разложены по пакетам так, чтобы их потом удобно было ставить.
    2. Издеваемся над содержимым директории с дебиановскими сборочными скриптами так, чтобы все файлы оказались в /opt (на нокии совсем маленькая rootfs, если кто не в курсе)
    3. Собираем под amd64
    4. Собираем платформозависимые бинарники в chroot-окружении из п. 2 (в scratchbox опять полезли ошибки, не стал разбираться)
    5. Капитально издеваемся над пакетами, меняя в них эти самые бинарники, правя зависимости, вставляя костыли

    Собственно, 4-ый шаг был облегчён наличием опции —disable-mcs-build, которую дяди из Novell специально придумали для таких случаев. Описывать процесс сборки не буду, он на этот раз (после 5-то неудачных попыток!) оказался весьма тривиален.

    Наборы пакетов и версии библиотек в Maemo и на убунте несколько отличаются, так что пришлось покорпеть. Но оно того стоит: удалось перенести на устройство нормальную систему раскиданных по пакетам библиотек (пока не полностью, но я над этим работаю) вместо 260-иметрового тарболла, который генерится при ./configure && make. Собственно, сейчас mono у меня сожрал около 27 метров /opt при весе пакетов в 12. При этом уже сейчас доступен практически весь .NET 2.0:

    System.dll, System.ServiceProcess.dll, System.Drawing.Design.dll, System.Transactions.dll, mscorlib.dll, System.Drawing.dll, System.EnterpriseServices.dll, System.Web.dll, System.ComponentModel.DataAnnotations.dll, System.IdentityModel.dll, System.Web.DynamicData.dll, Mono.Data.SqliteClient.dll, System.Configuration.dll, System.IdentityModel.Selectors.dll, System.Web.Extensions.Design.dll, Mono.Data.Sqlite.dll, System.Configuration.Install.dll, System.Management.dll, System.Web.Extensions.dll, System.Core.dll, System.Messaging.dll, System.Web.Routing.dll, System.Data.DataSetExtensions.dll, System.Runtime.Serialization.dll, System.Web.Services.dll, Mono.Messaging.dll, System.Data.dll, System.Security.dll, System.Windows.Forms.dll, System.Data.Linq.dll, System.ServiceModel.dll, System.Xml.dll, Mono.Security.dll, System.Design.dll, System.ServiceModel.Web.dll, System.Xml.Linq.dll

    Установить себе на устройство это чудо можно, добавив в sources.list следующую строку:

    deb http_://archive.kebrum.com/n900/ all main

    и установив пакет libmono-winforms2.0-cil, который потянет за собой всё остальное. К сожалению, пока больше никакие пакеты не переносил, ибо уже 4 утра, но обязательно этим займусь позже (мне же gtkшный софт переносить).

    Если кто-то захочет перенести свой софт на C# на N900 с использованием этой сборки, обязательно свяжитесь со мной, чтобы я держал вас в курсе событий.

    И не судите строго за орфографию с пунктуацией, ночь на дворе, глаза красны, очень спать хочется, да и по клавишам еле попадаю.

    UPD: С помощью лома и какой-то матери перенесено GTK# (пока не всё). Ну и нехилый такой кусок mono, необходимый для пакета mono-devel.

    Оцените статью