ValueConverter in Avalonia – 3 Wege, sie in XAML einzubinden

Avalonia ValueConverter

Avalonia hat sich als modernes, Cross-Platform-UI‑Framework für .NET etabliert. Ein zentrales Element bei der Datenbindung ist dabei der ValueConverter: eine kleine Logikschicht, die Werte und Objekte zwischen ViewModel und UI umwandeln kann. In anderen auf XAML basierenden Frameworks wie WPF ist das Konzept bereits seit Jahrzehnten bekannt – in Avalonia funktioniert es grundsätzlich ähnlich und wird auch häufig genutzt. Für die Art, wie wir ValueConverter im XAML-Code einbinden, gibt es allerdings wie so oft mehrere verschiedene Wege. Diesen Artikel möchte ich nutzen, um einige davon zu zeigen. Leser können sich damit eine Meinung bilden, welche davon für sie selbst die sinnvollste ist.

Weiterlesen …

Testautomatisierung mit Avalonia #2

Avalonia Testautomatisierung

Vor fast genau zwei Jahren habe ich bereits einen Artikel darüber geschrieben, wie Testautomatisierung auf Ebene der UI mit Avalonia möglich ist [1]. Der dort beschriebene Ansatz funktioniert, erfordert aber auch etwas Starthilfe in Form von einigen Utility-Klassen und der richtigen Konfiguration von Avalonia und Testframework. Hintergrund ist die Tatsache, dass Avalonia wie andere UI-Frameworks Single-Threaded ist und ähnlich wie WPF mit einem Application Objekt arbeitet. In automatisierten UI-Tests muss man sich somit darum kümmern, die Tests innerhalb des UI-Threads auszuführen, eine Instanz von Application zu teilen und die parallele Ausführung der Tests zu deaktivieren. Mit den Paketen Avalonia.Headless.XUnit oder Avalonia.Headless.NUnit sind diese Schritte aber glücklicherweise nicht mehr erforderlich. In diesem Artikel beschäftigen wir uns mit Avalonia.Headless.XUnit, da ich selber typischerweise mit XUnit arbeite.

Weiterlesen …

Avalonia UI – Per MarkupExtension auf das Betriebssystem eingehen

Auf Unterschiede eingehen

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.

Weiterlesen …

GPXviewer 2 – Mit Avalonia UI auf mehrere Plattformen

Es gibt eine lange Liste möglicher Frontend-Fameworks, zwischen denen .NET-Entwicklungsteams wählen können. Ein sehr spannender Kandidat ist Avalonia UI [1]. Ursprünglich als Cross-Plattform Alternative zu WPF gestartet, bietet es heute neben den bekannten Desktops von Windows, macOS und Linux auch Unterstützung für mobile Plattformen (Android, iOS), für den Browser (via WebAssembly) und als Alleinstellungsmerkmal auch für Embedded Linux. Für mein OpenSource Tool GPXviewer war für mich neben Windows insbesondere macOS relevant. Ganz einfach aus dem Grund, weil ich mittlerweile mehr Zeit auf meinem MacBook verbringe, als auf meinem Windows Laptop [2]. Daher habe ich mich entschieden, GPXviewer von WPF nach Avalonia UI zu portieren – daraus entstand dann das Projekt GPXviewer 2 [3]. In diesem und nachfolgenden Artikeln möchte ich einige Erfahrungen teilen, die ich damit sammeln durfte.

Weiterlesen …

Protobuf Nachrichten kompatibel erweitern

Kommunikation

Im letzten Blogartikel habe ich Protobuf als Serialisierungsformat vorgestellt [1]. In diesem Artikel möchte ich mich mit einem Thema beschäftigen, auf das man im Laufe eines Projekts früher oder später kommt: Wie erweitere ich eine Protobuf Nachricht so, dass die Änderung kompatibel zur vorherigen Version der Nachricht bleibt? Diese Frage taucht typischerweise dann auf, wenn eine zu ändernde Nachricht zwischen zwei oder mehr Services ausgetauscht wird, diese Services bei einem Update aber nicht gleichzeitig aktualisiert werden (können). Nehmen wir ein einfaches Beispiel: Ich möchte in neues Feld in einem Nachrichtentyp hinzufügen. Zunächst mache ich das am Service, welcher die Nachricht sendet und etwas später mache ich das bei den empfangenden Services. Geht das einfach so? Diese und weitere ähnliche Fragen möchte ich mit diesem Artikel beantworten. Ich beziehe mich bei den Beispielen ausschließlich auf C# und die Protobuf Implementierung im Paket Google.Protobuf.

Weiterlesen …

Protobuf in C# serialisieren und deserialisieren

Protobuf C#

Es gibt eine lange Liste von Formaten, welche für die Serialisierung und Deserialisierung von .NET Objekten verwendet werden kann. Xml und Json sind dabei lediglich die populärsten Vertreter. In diesem Artikel möchte ich mich mit Protobuf (oder ausgeschrieben „Protocol Buffers“) beschäftigen. Protobuf ist ein Format von Google. Es ist auf Performance und möglichst wenig Platzverbrauch ausgelegt. Zudem gibt es Unterstützung für viele verschiedene Programmiersprachen – C# ist nur eine davon. Protobuf lässt sich mit den Bibliotheken von Google in Java, Python, Objective-C, C++, Kotlin, Dart, Go, Ruby, PHP und natürlich C# verwenden. Es findet auch im Protokoll gRPC Verwendung. Letzteres ist einer der Gründe, warum ich mich mit Protobuf mehr in der Tiefe beschäftigt habe. Schließlich interessiert mich nicht nur die Serialisierung selbst oder Sachen wie die Performance, sondern auch wie mit Kompatibilitätsthemen (neue Felder, umbenannte Felder, etc.) umgegangen wird. In diesem Artikel schauen wir uns diese Themen anhand zweier alternativer Bibliotheken an. Diese sind Google.Protobuf von Google und protobuf-net von Marc Gravell.

Weiterlesen …

Testautomatisierung mit Avalonia

Testautomatisierung mit Avalonia

Testautomatisierung auf UI Ebene ist häufig nicht so einfach zu erreichen. Grund dafür können technische Fragestellungen sein. So gilt es, auf irgendeine Art das Rendering des UI-Frameworks abzubilden. Ebenso gilt es, mögliche Usereingaben zu emulieren oder Eingabeelemente an der UI zu identifizieren. Auch zeitliche Aspekte spielen mit rein, so ist ein „Warte eine Sekunde…“ in einem automatisierten Test i. d. R. eine eher schlechte Idee. Doch es gibt auch Herausforderungen, die aus den Testfällen selbst entstehen. Versucht man etwa, ein Drag-Drop Verhalten automatisiert zu testen, beißt man sich dabei schon mal gerne die Zähne aus. Ich persönlich versuche UI Tests daher auf einem niedrigen Level zu halten, setze sie also primär für einfach zu überblickende Geradeausfälle ein. Mit Avalonia habe ich UI Tests zuletzt bei meinem Nuget-Paket RolandK.AvaloniaExtensions [1] eingesetzt. Hier ging es mir darum, dass die dort definierten Basisklassen und Features wie die Dependency Injection einwandfrei in einer Avalonia Applikation funktionieren.

Weiterlesen …

Avalonia FluentTheme zur Laufzeit wechseln

Avalonia Theme Switch

Viele moderne Applikationen bieten neben einer ansprechenden UI auch den Wechsel zwischen verschiedenen Themes an. Für gewöhnlich wird zumindest zwischen Hell und Dunkel unterschieden. Gleiches gilt für das Betriebssystem selbst – Windows und macOS bieten dem User jeweils die Wahl zwischen Hell und Dunkel. Auch Avalonia bietet mit dem FluentTheme seit Version 0.10 einen sehr einfachen Weg an, zwischen hellen und dunklen Modus zu unterscheiden. Typischerweise wird das FluentTheme in der App.xaml angegeben und bekommt als Mode entweder „Light“ oder „Dark“. In diesem Artikel wollen wir uns damit beschäftigen, wie diese Einstellung zur Laufzeit der Applikation verändert werden kann. Weiterhin schauen wir uns an, wie man unter Windows den aktuell konfigurierten Theme herausbekommt und sogar auf Änderung des aktuellen Theme reagieren kann.

Weiterlesen …

Avalonia Applikationen übersetzen

Avalonia Applikationen übersetzen

In den letzten Monaten habe ich vermehrt Artikel über das Cross-Platform Framework Avalonia geschrieben. Für mich persönlich hat sich das Framework mittlerweile zum Standard für Desktop-Applikationen entwickelt. Es kann fast alles, was man braucht und läuft auf allen gängigen Desktop Plattformen (Windows, macOS, Linux) stabil. In diesem Artikel möchte ich mich mit einem Thema beschäftigen, auf das die meisten Softwareentwickler bei UIs irgendwann stoßen: Applikationen in andere Sprachen übersetzen. Auch wenn man nicht den akuten Bedarf hat, so sollte man UIs möglichst von vorne herein darauf vorbereiten, dass sie übersetzbar sind. Übersetzung im Nachhinein einzubauen kann häufig sehr schwierig sein. Insbesondere, wenn Daten von außen bereits behaftet mit einer bestimmten Sprache in der eigenen Applikation ankommen.

Weiterlesen …

Das DataGrid von Avalonia

Avalonia with DataGrid

Das auf .Net basierende Cross-Plattform UI Framework Avalonia verfügt über eine große Palette an Standard-Controls. Es ist vieles dabei, was man als Entwickler typischerweise braucht. So gibt es etwa diverse Eingabeboxen, Controls für Auflistungen und welche, über die das Layout beeinflusst werden kann. Wenn ich auf Business-Applikationen schaue, fällt mir zudem noch ein sehr wichtiges ein, welches Avalonia mitbringt: Das DataGrid. Die Aufgabe eines DataGrids besteht grundsätzlich darin, eine mehr oder weniger lange Liste von Objekten in tabellarischer Form darzustellen. Jede Zeile ist ein solches Objekt, jede Spalte bezieht sich auf eine Eigenschaft. Daneben gibt es typischerweise Anforderungen wie zum Beispiel Sortierung, Filterung oder Gruppierung. Das DataGrid in Avalonia liefert diese Features entweder direkt oder bringt sie über den kleinen Umweg einer CollectionView im ViewModel mit. In diesem Artikel möchte ich mich mit den Features beschäftigen, welche das DataGrid in Avalonia im Standard mitbringt und wie man diese verwendet.

Weiterlesen …