Avalonia UI rendert alle Elemente selbst. Das hat insbesondere den Vorteil, dass die eigene Applikation und damit das eigene Corporate Branding auf jeder Plattform gleich aussieht. Es gibt noch einige andere Vorteile dieses Ansatzes. In diesem Artikel möchte ich aber darauf eingehen, wie man mit Stellen umgehen kann, an denen es Unterschiede zwischen den verschiedenen Betriebssystemen gibt. Es gibt i. d. R. nur Wenige, eines davon ist die Menüleiste. Für Windows und Linux wird sie typischerweise im Hauptfenster ganz oben angezeigt. Unter macOS ist das anders – dort stellt das Betriebssystem selbst eine Menüleiste am oberen Bildschirmrand bereit. Somit ist es unter macOS gar nicht notwendig, das Hauptmenü selbst zu zeichnen. Hier im Artikel beschreibe ich, wie ich das Thema bei GPXviewer 2 mittels einer MarkupExtension gelöst habe.
Inhalt
Das Betriebssystem erkennen
Zunächst einmal möchte ich mich mit der Frage beschäftigen, wie wir das aktuelle Betriebssystem überhaupt erkennen. In .NET gibt es dafür einen sehr einfachen Weg: Die Klasse OperatingSystem [1]. Wenn wir beispielsweise wissen möchten, ob wir uns gerade in macOS befinden, rufen wir die Methode OperatingSystem.IsMacOS() auf. Vergleichbare Methoden gibt es auch für Windows, Linux, Android, iOS und viele Weitere.
MarkupExtension zur Erkennung des Betriebssystems
Um innerhalb des XAML Codes das Betriebssystem abzufragen, hilft uns die Klasse OperatingSystem zunächst noch wenig. Ein für mich eleganter Weg, diese Funktionalität innerhalb des XAML Codes verfügbar zu machen, ist eine MarkupExtension. Nachfolgend als Code-Beispiel eine MarkupExtension, die ich im Rahmen der Entwicklung von GPXviewer 2 [2] genutzt habe. In diesem Fall wird geprüft, ob man sich eben nicht auf macOS befindet. Bei allen Betriebssystemen außer macOS wird entsprechend true zurückgeliefert, für macOS false.
public class IsNonMacOsExtension : MarkupExtension { public override object ProvideValue(IServiceProvider serviceProvider) { return OperatingSystem.IsMacOS(); } }
Mithilfe einer solchen MarktupExtension ist es nun sehr einfach, im XAML Code auf Besonderheiten des Betriebssystems einzugehen. Nachfolgend die Stelle im Code von GPXviewer 2, an der mithilfe dieser MarkupExtension entschieden wird, ob das Hauptmenü gerendert werden soll, oder nicht.
... <Menu DockPanel.Dock="Top" IsVisible="{localMarkup:IsNonMacOs}"> <MenuItem Header="File"> ... </Menu> ...
Somit wird das Hauptmenü nur dann gerendert, wenn die Applikation nicht in macOS ausgeführt wird. Für macOS wiederum nutze ich das XAML Element NativeMenu [3]. Das vollständige Coding dazu ist unter [4] abrufbar.
Fazit
Mithilfe der APIs von .NET ist es sehr einfach, das aktuelle Betriebssystem zu erkennen, um damit anschließend auf Besonderheiten einzugehen. Solche Besonderheiten gibt es für Avalonia UI Applikationen aus meiner Sicht nicht viele – es gibt sie aber.
Verweise
- Die Klasse OperatingSystem
https://learn.microsoft.com/en-us/dotnet/api/system.operatingsystem - GPXviewer 2
https://www.rolandk.de/wp-kats/opensource/rk-gpx-viewer/ - NativeMenu für eigene Elemente in der Menüleiste unter macOS
https://docs.avaloniaui.net/docs/reference/controls/nativemenu - Vollständiges Codebeispiel zur Nutzung der MarkupExtension in GPXviewer 2
https://github.com/RolandKoenig/GpxViewer2/src/GpxViewer2/MainWindow.axaml
Ebenfalls interessant
- Als .NET Entwickler auf dem MacBook Pro
https://www.rolandk.de/wp-posts/2024/05/als-net-entwickler-auf-dem-macbook-pro/ - Cross-Plattform GUI mit C# und Avalonia UI
https://www.rolandk.de/wp-posts/2020/07/cross-platform-gui-mit-c-und-avalonia/ - GPXviewer 2 – Mit Avalonia UI auf mehrere Plattformen
https://www.rolandk.de/wp-posts/2025/01/gpxviewer-2-mit-avalonia-ui-auf-mehrere-plattformen/