Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 16 Min.

UI-Gestaltung mit Uno

Architektur, Ökosystem, UX/UI-Strategien und Tooling der Uno Platform.
© EMGenie

Moderne Anwendungen müssen heute auf einer Vielzahl von Endgeräten laufen (Desktop, Web und Mobile). Die Uno Platform ermöglicht genau das: Sie setzt auf das WinUI-basierte XAML/C#-Modell von Microsoft und macht es auf iOS, Android, macOS, Linux und WebAssembly nutzbar. Entwickler können so aus einer einzigen Codebasis heraus native, leistungsfähige Apps erstellen. Dieser Artikel erklärt, warum Uno für Cross-Plattform-UIs sinnvoll ist, wie die Architektur funktioniert, welche UX-/UI-Konzepte es unterstützt und welche Tools und Libraries es im Ökosystem gibt. Praxisnahe Codebeispiele konkretisieren diese einzelnen Themenbereiche.

Uno für plattformübergreifende UIs

Die Uno Platform wurde als Open-Source-.NET-Plattform für Mobile-, Web-, Desktop- und Embedded-Apps mit einer gemeinsamen Codebasis entwickelt. Dabei übernimmt Uno das gesamte WinUI- beziehungsweise UWP-XAML-API und macht es auf allen unterstützten Plattformen lauffähig. Bestehende WinUI- oder UWP-Steuerelemente lassen sich oft eins zu eins weiterverwenden, manchmal müssen sie lediglich neu kompiliert werden. In Kombination mit C# ergibt sich ein hoher Wiederverwendungsgrad: Bis zu 99 Prozent von Geschäftslogik und UI-Definition lassen sich laut Uno-Dokumentation beibehalten. Entwicklerteams profitieren dadurch von ihren Kenntnissen in XAML/C# und den Tools des Microsoft-Ökosystems (Visual Studio, VS Code, Rider et cetera).

Außerdem wird Uno als pixelgenau (Pixel-perfect) beworben, das bedeutet, dass unabhängig vom Betriebssystem dieselben Layout- und Zeichenbefehle genutzt werden, um gleiche Optik und Benutzerführung zu gewährleisten. Gleichzeitig kann Uno auf jeder Plattform die nativen Steuerelemente verwenden oder über die zentrale Skia-Engine rendern. Die Plattform ist also flexibel: Sie liefert überall native Performance und Aussehen, während nur eine Codebasis gepflegt werden muss. 

Zu den weiteren Features zählen integrierte Themen-/Designsysteme: Mit den Uno-Themes [3] lassen sich Apps gezielt an Plattform-Guidelines anpassen. Zum Beispiel sind via NuGet-Komponente ein Material-Design für Android-UI sowie ein Cupertino-Design für iOS verfügbar, falls man den nativen Look bevorzugt. Wer plattformübergreifend entwickeln muss und Windows/XAML-Know-how hat, findet in der Uno Platform deshalb eine produktive, aktuelle Lösung mit folgenden Kernfeatures:

  • Ein Code, viele Plattformen: Einfache Wiederverwendung von WinUI-Code.
  • Microsoft-Ökosystem: Nutzung von C#, .NET 8+, Visual Studio, .NET MAUI- oder Community-Toolkit-Bibliotheken.
  • Pixel-perfect und nativ: Einheitliche UIs über Skia-Rendering oder native UI-Frameworks.
  • Open Source: Ohne Lizenzkosten, mit wachsender Community; bezahlt werden muss nur für das erweiterte Tooling namens Hot Design.

Installation, IDEs und Toolchains

Die Entwicklung mit der Uno Platform ist auf allen gängigen Betriebssystemen möglich, das heißt unter Windows, macOS und Linux. Wichtig ist lediglich eine moderne .NET-Version (ab .NET 8, empfohlen wird .NET 9) sowie eine unterstützte IDE oder ein Editor. Folgende Installationen sind notwendig:

  • .NET SDK: Uno Platform unterstützt .NET 8+; am besten installiert man das aktuelle .NET SDK.
  • Uno Templates: Mit dotnet new install Uno.ProjectTemplates erhält man alle Uno-spezifischen Projektvorlagen. Damit lässt sich mit einem Befehl wie dotnet new unoapp -o MyApp eine neue App für alle Zielplattformen generieren.
  • NuGet-Pakete: Abhängig vom Szenario fügt man Toolkit/Theme/Extensions-Pakete hinzu, zum Beispiel Uno.Toolkit.UI, Uno.Extensions.Hosting, UnoThemes.Material.
  • Pooling und Builds: Uno unterstützt das Pooling von Ressourcen. Das heißt, dass eine gemeinsame Build- und Asset-Pipeline für alle Plattformen. Icons, Styles, Fonts und XAML-Ressourcen nur einmal gepflegt und beim Build für jede Zielplattform verteilt wird. Damit reduziert sich der Wartungsaufwand enorm.

 

Die Uno Platform ist offen gestaltet. Unterstützt werden unterschiedliche Entwicklungsumgebungen (IDEs) und Editoren:

  • Visual Studio 2022 (Windows): Vollintegration mit Uno-Templates, Emulatoren (Android/iOS), Debugging und Hot Reload/Hot Design.
  • Visual Studio Code (Windows, Mac, Linux): Flexibler, leichtgewichtiger Editor. Dank offizieller Uno- und C#-Erweiterungen unterstützt er XAML-IntelliSense, Hot Reload und Figma-Integration.
  • JetBrains Rider: Wird ebenfalls unterstützt, mit XAML-Preview und Debugging.
  • Uno Platform Studio: Als übergreifende Ergänzung, um Hot Reload/Hot Design in allen Umgebungen zu erlauben.

 

Eine typische Toolchain für das Entwickeln plattformübergreifender Apps unter Windows sieht so aus:

  • Betriebssystem Windows 11.
  • IDE Visual Studio 2022 mit den Workloads .NET Multi-platform App UI development und Desktop development with C++.
  • Uno Platform Solution Templates über NuGet.
  • Uno Platform Studio (Hot Reload/Hot Design).

 

Der Vorteil dieser Kombination der Entwicklungstools ist die Nutzung von Visual Studio, ein gutes Debugging-Erlebnis auf allen Plattformen und die Vertrautheit der Tools für viele Entwickler. Eine alternative Toolchain setzt auf Visual Studio Code (VS Code), welches für Windows, macOS und Linux zur Verfügung steht:

  • Betriebssystem Windows, Linux oder macOS; installiertes .NET SDK.
  • VS Code mit folgenden Erweiterungen: C# Dev Kit (Microsoft) für IntelliSense und Debugging.
  • Uno Platform for VS Code für Templates, Uno Studio sowie Hot Reload.
  • Uno-Figma-Plug-in für Design-to-Code-Integration.
  • XAML Styler für saubere XAML-Struktur, optional.
  • Build & Run: per CLI (dotnet build, dotnet run) oder direkt im Editor.

 

Die Vorteile eines Editors wie Visual Studio Code liegen in einer leichtgewichtigen Nutzbarkeit und dass dieser auf jedem Betriebssystem funktioniert.

Der Autor erlaubt sich an dieser Stelle eine Empfehlung: Wer sich schnell in bestehenden WinUI/XAML-Stacks zu Hause fühlen möchte, nutzt Visual Studio auf Windows. Entwickler, die plattformunabhängig entwickeln möchten, beispielsweise auch auf unterschiedlichen Betriebssystemen im Team (macOS/Linux), nutzen VS Code.

Für beide Varianten ist Uno Platform Studio das geeignete Tool, um Benutzeroberflächen teilweise interaktiv zu gestalten (Hot Design).

Architektur: WinUI-Paradigma auf allen Plattformen

Unter der Haube implementiert Uno das komplette WinUI/WinRT-API auf Nicht-Windows-Systemen mit den Paketen Uno.WinUI und Uno.WinRT. Entwickler schreiben ihr UI weiterhin in gewohnter XAML-Syntax oder als C#-Markup, und während des Kompilierens (Build Time) wandelt Uno den XAML-Code per Roslyn-Generator in C#-Code um. Auf diese Weise erhält man zur Laufzeit ein natives UI-Framework für jedes Zielsystem.

Im Rendering unterstützt Uno zwei Modi: Native und Skia. In nativen Modus werden auf jeder Plattform die Standard-UI-Elemente verwendet (zum Beispiel UIView auf iOS, ViewGroup auf Android und DOM-Elemente im Web). Dadurch bekommt man die volle Plattform-Integration und Zugänglichkeit.

Im Skia-Modus rendert Uno dagegen alles auf eine einzige Hardware-beschleunigte Canvas (unterstützt Metal, OpenGL oder WebGL). Dieser Modus liefert auf allen Plattformen exakt dasselbe Pixel-Ergebnis und ist sehr performant, besonders bei vielen dynamischen UI-Elementen. In Projektvorlagen ist Skia aktiv, sofern man diese Voreinstellung nicht ändert.

Die hohe Kompatibilität zeigt sich auch im Build-System: Uno-Projekte nutzen .NET 8+ (Mobil, Desktop, WebAssembly) und MSBuild, automatisieren dabei die Transformation von Assets und Ressourcen für jedes Zielsystem. Zusätzlich erlaubt Uno das Einbinden nativer Komponenten über APIs. Bild 1 zeigt einen Blick auf die Architektur der Uno Platform.

High Level Architektur der Uno Plattform (Bild 1)

High Level Architektur der Uno Plattform (Bild 1)

© Autor

UX und UI: Barrierefreiheit, responsive Patterns

Auch die Benutzererfahrung sollte plattformübergreifend konsistent sein. Die Uno Platform greift hier auf die Mechanismen von WinUI zurück und erweitert sie für alle Plattformen. So ist Accessibility (Barrierefreiheit) integriert. Uno.UI implementiert einen großen Teil des UI-Automation-APIs von WinUI, sodass Screenreader und andere Hilfstechnologien auf allen Systemen funktionieren. Beispielsweise werden in XAML angegebene Eigenschaften wie AutomationProperties.Name oder AutomationId zur Laufzeit in die passenden Plattform-Felder übernommen (Android: ContentDescription, iOS: AccessibilityIdentifier, Web: aria-label). So kann man dieselben XAML-Attached-Properties nutzen, um Elemente beschreibbar und bedienbar zu machen – eine wichtige Voraussetzung für zugängliche Apps.

Beim responsiven Design nutzt Uno alle aus WinUI bekannten Techniken. Mit AdaptiveTrigger und VisualStateManager kann XAML Layouts dynamisch an verschiedene Fenstergrößen oder Orientierungen anpassen. Zusätzlich bietet das Uno-Toolkit spezielle Controls und Layouthilfen für ein responsives Design. Zum Beispiel ermöglicht der Responsive-View-Container, unterschiedliche XAML-Templates je nach Bildschirmbreite zu definieren. Das Steuerelement passt sich durch die dynamische Auswahl des richtigen Templates an unterschiedliche Bildschirmgrößen an. Dabei werden die aktuelle Bildschirmbreite und die definierten Vorlagen betrachtet. Da nicht alle Vorlagen einen Wert benötigen, sorgt das Steuerelement für eine reibungslose Benutzererfahrung, indem es die kleinste definierte Vorlage auswählt, die die Anforderungen an die Breite erfüllt. Wird keine Übereinstimmung gefunden, wird die größte definierte Vorlage verwendet. Ein einfaches Beispiel mit responsiven Layouts sieht wie folgt aus:

 

xmlns:utu="using:Uno.Toolkit.UI"
 <utu:ResponsiveView>
   <!-- note: -->
   <utu:ResponsiveView.NarrowTemplate>
     <DataTemplate>
       <!-- Narrow content -->
     </DataTemplate>
   </utu:ResponsiveView.NarrowTemplate>
   <utu:ResponsiveView.WideTemplate>
     <DataTemplate>
       <!-- Wide content -->
     </DataTemplate>
   </utu:ResponsiveView.WideTemplate>
 </utu:ResponsiveView>

 

Trotz plattformübergreifender Codebasis bleibt das UI konsistent – dank des pixelgenauen Renderings und optisch einheitlicher Themes. Schriften und Abstände erscheinen überall gleich. Gleichzeitig lässt Uno das Aneinanderreihen nativer UX-Konventionen zu: Man kann etwa für iOS automatisch Cupertino-Icons verwenden oder systembedingte Abstände wählen. Die Themes-Bibliothek stellt Material-, Fluent- und Cupertino-Stile bereit. Entwickler sind auf diese Weise flexibel: Sie behalten gemeinsame UI-Logik, können aber Design-Abweichungen pflegen, um den Benutzererwartungen jeder Plattform gerecht zu werden.

Ökosystem

Ein umfassendes Ökosystem ergänzt die Plattform. Klassische MVVM-Muster funktionieren in Uno genauso wie in jeder anderen auf XAML basierenden App. Man kann vertraute Frameworks, wie das CommunityToolkit.Mvvm einsetzen, um ViewModels mit INotifyPropertyChanged und ICommand zu verknüpfen. Beispielsweise lässt sich mit dem Community-Toolkit der ViewModel-Code nach folgendem Muster schreiben:

 

public partial class MainViewModel : ObservableObject
 {
   [ObservableProperty]
   private WeatherInfo _currentWeather;
   public MainViewModel(IWeatherService weather)
   {
     _weather = weather;
     LoadWeather();
   }
   // ...
 } 

 

Eine neuere Option im Uno-Ökosystem heißt Model-View-Update-eXtended, kurz MVUX. Dieses vom Uno-Team entwickelte Muster verbindet die Vorzüge von MVU (einfacher Datenfluss, Immutability) mit dem Databinding von MVVM. MVUX ermutigt zur Verwendung von Immutable Records und bietet automatische ViewModel-Generierung mittels Source-Generatoren. So ergeben sich deklarative, nebenläufigkeitsfreundliche Zustandsaktualisierungen bei gleichzeitigem XAML-Binding-Support. In der Praxis schreibt man einfach unveränderliche (immutable) Datentypen und Methoden zur Zustandsänderung, und Uno erzeugt das nötige ViewModel. 

Dieser MVUX-Ansatz adressiert komplexe Szenarien mit vielen asynchronen Operationen besonders elegant. Für Einsteiger bietet sich MVVM weiterhin an; erfahrene Entwickler komplexer Apps profitieren von MVUX. Einen Vergleich des Datenflusses zwischen den Schichten bei MVVM und bei MVUX zeigt Bild 2.

Datenfluss von MVVM versus MVUX (Bild 2)
Datenfluss von MVVM versus MVUX (Bild 2) © Autor

Für Dependency-Injection und Hosting stellt Uno ebenfalls Infrastruktur bereit. Die Bibliothek Uno.Extensions integriert das Paket Microsoft.Extensions.Hosting, sodass man in der Datei App.xaml.cs einen HostBuilder verwenden kann. Dienste und Services (zum Beispiel für Networking, Datenbanken et cetera) registriert man mit ConfigureServices über AddSingleton oder ähnliche Methoden. So werden ViewModels oder Services einfach per Konstruktor-Injektion aufgelöst. Hier ein Beispiel dazu:

 

var builder = this.CreateBuilder(args)
 .UseStudio() // Neu: aktiviert HotReload/HotDesign bei .NET 9+
 .ConfigureServices((ctx, services) =>
 {
   services.AddSingleton<IWeatherService, WeatherService>();
   services.AddSingleton<MainViewModel>();
 });
 var host = builder.Build();

 

Das ist analog zu üblichen .NET-Anwendungen. Nach dem Build ruft man beispielsweise folgenden Befehl auf, um View-Model-Instanzen zu beziehen:

 

DataContext = host.Services.GetRequiredService<MainViewModel>();

 

Wichtig: Ab Uno.Sdk 5.5+ sollte man UseStudio() anstelle von EnableHotReload() nutzen, um Hot-Reload-Funktionen einzuschalten. 

Eine weitere wichtige Ergänzung ist die Bibliothek Uno.Toolkit.UI (NuGet Uno.Toolkit.UI beziehungsweise Uno.Toolkit.WinUI), die erweiterte Controls bereitstellt. Neben Standard-Layouts findet man dort Material-Design-Elemente wie Card, Chip und TabBar, mobile Navigationselemente wie NavigationBar, DrawerControl oder TabBarItem. Die Toolkit-Komponenten sind für responsives Verhalten optimiert und können im XAML-Code wie normale Controls verwendet werden.

Zusätzlich sorgt Uno.Themes dafür, dass Material- beziehungsweise Cupertino- und Fluent-Styles leicht angewendet werden können. Per NuGet fügt man Uno.Themes.Material oder Uno.Themes.Cupertino hinzu, um gebrauchsfertige Resource Dictionaries mit Farb- und Control-Styles zu laden. Damit passen sich Steuerelemente automatisch an die Plattformrichtlinien an.

Kurz: Die Uno-Plattform hat eine umfassende Toolchain und Bibliotheken – von UI-Controls über Muster (MVVM/MVUX) bis zu Hilfs-Frameworks (DI, Navigation) –, die den Entwickleralltag erleichtern und den Fokus auf die eigentliche App-Logik legen.

Hot Reload, Hot Design, Uno Platform Studio

Die Entwicklung mit Uno kann durch spezialisierte Werkzeuge stark beschleunigt werden. Ein zentrales Element ist Uno Platform Studio. Das ist ein Satz von Tools und Erweiterungen für Visual Studio, VS Code, Rider et cetera, der vor allem Hot Reload und das neue Hot Design kombiniert:

  • Hot Reload: Wie in .NET allgemein ermöglicht Uno Hot Reload, dass Änderungen in XAML oder C# sofort in der laufenden App sichtbar werden, ohne Neugenerierung oder Neustart. Uno Hot Reload unterstützt dabei alle Plattformen (iOS, Android, WebAssembly, Skia-Targets) und gängige IDEs (Visual Studio 2022, VS Code, Rider). Entwickler können zum Beispiel während des Debuggens den Button mit dem Flammensymbol klicken oder die Tastenkombination [Alt]+[F10] drücken und sehen ihre UI-Modifikationen unmittelbar. Laut Uno-Dokumentation können fast alle UI-Änderungen live übernommen werden, das heißt XAML-Dateien, Styles, DataTemplates, Bindings, x:Bind-Ausdrücke und so weiter. Hot Reload ist tief in die Plattform integriert: Unter .NET 9+ genügt in der Datei App.xaml.cs bereits der Aufruf von UseStudio(), um Hot Reload und Hot Design zu aktivieren. Eine visuelle Anzeige im Fenster (ein kleines Blitz-Symbol) informiert über erfolgreiche Aktualisierungen.
  • Hot Design: Dieses völlig neue Feature macht die Anwendung zur Laufzeit selbst zum Designer. Man kann eine laufende App „einfrieren“ und visuell editieren – ähnlich wie in einem WYSIWYG-Editor – während sie auf einem beliebigen Gerät geöffnet ist. Laut Uno-Team verwandelt Hot Design die App live in einen visuellen Editor, der Änderungen in Echtzeit synchron mit dem XAML-Code durchführt. Praktisch bedeutet das: Mit einem Klick hat man im Editor die aktuelle Ansicht vor sich, kann UI-Elemente positionieren, Styles ändern oder neue Controls hinzufügen und sieht die Wirkung sofort auf dem Device (der Zustand bleibt erhalten). Jede Anpassung wird direkt in den Code zurückgeschrieben. Es entsteht also ein bidirektionaler Flow zwischen Code und Designer. Hot Design unterstützt alle gängigen IDEs und Betriebssysteme (Visual Studio, VS Code, Rider und Windows, macOS, Linux). Es ist ab .NET 9 mit XAML verfügbar und läuft auf allen Plattformen außer WinAppSDK. Der Vorteil: Einmalige Änderungen lassen sich sofort testen, auch mit echten Daten anstelle statischer Mockups. Uno Platform Studio bietet zudem ein Design-to-Code-Plug-in für Figma: Designer können Benutzeroberflächen in Figma entwerfen und per Plug-in direkt nach XAML- beziehungsweise C#-Code exportieren. So wird der Roundtrip zwischen UI-Design und Code stark vereinheitlicht.

 

In der Praxis bedeutet das für Entwickler, dass man unmittelbar Feedback bei der UI-Erstellung bekommt und schnellere Iterationen möglich werden. Der kombinierte Einsatz von Hot Reload und Hot Design verkürzt Debug-Zyklen erheblich. Darüber hinaus bietet das Uno-Toolset zahlreiche weitere Helfer: einen Template-Wizard (Bild 3) in Visual Studio für neue Projekte (inklusive Einbindung von Toolkit/Theme-Features), Kommandozeilen-Tools (dotnet new unoapp -o MyApp) und einen umfangreichen Uno Playground, um XAML-Code direkt im Browser auszuprobieren (Bild 4).

Template-Wizard zum Erstellen von Uno-Apps (Bild 3)

Template-Wizard zum Erstellen von Uno-Apps (Bild 3)

© Autor
 Uno-Playground zum Testen von XAML-Code (Bild 4)

Uno-Playground zum Testen von XAML-Code (Bild 4)

© Autor

All das ergibt zusammen mit der Figma-Integration und klassischen Debugging-Features ein sehr modernes Toolset für die plattformübergreifende .NET-Entwicklung.

Snippets in XAML und C#

Nach all den theoretischen Grundlagen folgen nun einige Code-Schnipsel, die den praktischen Umgang mit Uno zeigen. Listing 1 codiert eine XAML-Seite mit einem Button, die plattformübergreifend überall funktioniert.

Listing 1: Einfaches Beispiel
<!-- MainPage.xaml -->
<Page
  x:Class="MyApp.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <StackPanel HorizontalAlignment="Center"
    VerticalAlignment="Center">
    <TextBlock Text="Willkommen bei Uno!" FontSize="24" Margin="0,0,0,20"/>
    <Button Content="Klick mich!" Click="Button_Click" Padding="10,5"/>
  </StackPanel>
</Page>
// MainPage.xaml.cs
public partial class MainPage : Page
{
  public MainPage()
  {
    this.InitializeComponent();
  }
  private void Button_Click(object sender, RoutedEventArgs e)
  {
  // Diese Logik läuft auf jeder Plattform
  Content = new TextBlock {
    Text = "Der Button wurde geklickt!", FontSize = 18, Padding="10" };
  }
}
 

Ob man diese Seite nun in iOS, Android, im Browser (WebAssembly) oder auf Windows lädt: Layout und Verhalten bleiben gleich. Uno übersetzt das <Button>-Element intern in den nativen Button der Plattform oder zeichnet es über Skia.

Im zweiten Beispiel wird ein adaptives Layout aufgebaut. Wir erstellen ein Navigationssystem, welches auf großen Bildschirmen als Navigationsleiste angezeigt wird und auf kleinen Bildschirmen durch eine TabBar ersetzt wird (Listing 2).

Listing 2: Adaptives Layout
<VisualStateManager.VisualStateGroups>
  <VisualStateGroup>
    <VisualState x:Name="WideView">
      <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="720"/>
      </VisualState.StateTriggers>
      <VisualState.Setters>
        <Setter Target="NavMenu.Visibility" Value="Visible"/>
        <Setter Target="TabBar.Visibility" Value="Collapsed"/>
      </VisualState.Setters>
    </VisualState>
    <VisualState x:Name="NarrowView">
      <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="0"/>
      </VisualState.StateTriggers>
      <VisualState.Setters>
        <Setter Target="NavMenu.Visibility" Value="Collapsed"/>
        <Setter Target="TabBar.Visibility" Value="Visible"/>
      </VisualState.Setters>
    </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups> 

Dieses Muster schaltet je nach Fensterbreite zwischen zwei Layout-Alternativen um. Mit dem Uno Toolkit kann man stattdessen auch das ResponsiveView-Control verwenden:

 

<uto:ResponsiveView>
   <uto:ResponsiveView.NarrowTemplate>
     <DataTemplate>
       <StackPanel>
         <TextBlock Text="Ansicht für enge Bildschirme"/>
       </StackPanel>
     </DataTemplate>
   </uto:ResponsiveView.NarrowTemplate>
   <uto:ResponsiveView.WideTemplate>
     <DataTemplate>
       <StackPanel><TextBlock Text=”Ansicht für breite Bildschirme”/>
       </StackPanel>
     </DataTemplate>
   </uto:ResponsiveView.WideTemplate>
 </uto:ResponsiveView> 

 

Je nach Bildschirmbreite wählt Uno das passende Template aus. Solche Controls machen eine plattformübergreifende UX besonders einfach. 

Ein weiterer Quellcodeausschnitt betrachtet das Einbinden von Services via Dependency-Injection in C#-Code in der Datei App.xaml.cs:

 

public App()
 {
   this.InitializeComponent();
   var hostBuilder = this.CreateBuilder(args)
   .UseStudio() // aktiviert HotReload/HotDesign
   .ConfigureServices((context, services) =>
     {
       services.AddSingleton<IWeatherService, WeatherService>();
       services.AddSingleton<MainViewModel>();
     });
   var host = hostBuilder.Build();
   host.Services.GetRequiredService<  MainViewModel>(); // startet ViewModel-Lebenszyklus
   // ...
 } 

In der Datei MainPage.xaml.cs könnte man das MainView-Model dann per Konstruktor oder DataContext verwenden. Dieses Muster ist identisch zu anderen .NET-Anwendungen.

Ein Uno-Beispiel

Dieser erste Artikel zu Uno schließt mit dem Beispiel einer minimalistischen To-do-App. Diese soll lokal definierte Aufgaben anzeigen, die der Benutzer abhaken kann. Sie bietet folgende Basisfunktionen:

  • Eine Überschrift (Meine Aufgabenliste).
  • Eine Aufgabenliste mit Checkboxen zum Abhaken.
  • Ein Eingabefeld für neue Aufgaben als Platzhalter.

 

Die App soll man auf Desktop, Smartphones sowie im Browser ausführen können. Angelegt wird das neue Projekt über den Visual-Studio-Projektassistenten. Dabei sind folgende Schritte erforderlich:

  • Visual Studio starten,
  • Menü: Datei | Neues Projekt...,
  • Vorlage auswählen: Uno Platform App,
  • Projektname: MyTodoApp,
  • Zielplattformen auswählen: Windows (WinUI), WebAssembly, Android und iOS.

 

Visual Studio erzeugt dann eine Lösung mit einer vollständigen Multi-Plattform-Struktur, die Sie in Bild 5 sehen können, mit:

  • MyTodoApp: Shared-Projekt mit XAML und C#,
  • MyTodoApp.WinUI: Windows Desktop,
  • MyTodoApp.Wasm: WebAssembly,
  • MyTodoApp.Droid: Android,
  • MyTodoApp.iOS: iOS/iPadOS.
Projektstruktur der To-do-App (Bild 5)

Projektstruktur der To-do-App (Bild 5)

© Autor

Damit steht eine vollständige Multi-Plattform-Struktur bereit. Im nächsten Schritt wird die Benutzeroberfläche per XAML-Code beschrieben, die in der Datei MainPage.xaml abgelegt wird. Listing 3 zeigt den Code dazu. Und in Listing 4 sehen Sie den C#-Code des Beispiels mit der Geschäftslogik, welche in der Datei MainPage.xaml.cs abgelegt wird.

Listing 3: XAML-Code der MyTodoApp
<Page
  x:Class="ToDo.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="using:ToDo">
  <StackPanel Padding="20" Spacing="10">
    <!-- Überschrift -->
    <TextBlock Text="Meine Aufgabenliste" FontSize="24" FontWeight="Bold" />

    <TextBox x:Name="NewTaskTextBox" PlaceholderText="Neue Aufgabe hinzufügen" />
    <Button Content="Hinzufügen" Click="AddTask_Click"/>
    
    <!-- Aufgabenliste -->

    <ListView ItemsSource="{Binding Tasks}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <CheckBox Content="{Binding Description}" IsChecked="{Binding IsDone, Mode=TwoWay}" />
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </StackPanel>
</Page> 
Listing 4: Geschäftslogik der MyTodoApp
using System.Collections.ObjectModel;
namespace ToDo;
public sealed partial class MainPage : Page
{
  public ObservableCollection<TaskItem> Tasks {
  get; set; } = new();
  public MainPage()
  {
    this.InitializeComponent();
    // Statische Aufgaben hinzufügen
    Tasks.Add(new TaskItem { Description = "Einkaufen gehen", IsDone = false });
    Tasks.Add(new TaskItem { Description = "Projekt fertigstellen", IsDone = false });
    Tasks.Add(new TaskItem { Description = "Müll rausbringen", IsDone = false });
    // Binding-Kontext setzen
    this.DataContext = this;
  }
  private void AddTask_Click(object sender, RoutedEventArgs e)
  {
    var text = NewTaskTextBox.Text?.Trim();
    if (!string.IsNullOrEmpty(text))
    {
      Tasks.Add(new TaskItem { Description = text, IsDone = false });
      NewTaskTextBox.Text = "";
    }
  }
} 

Dieses minimale Beispiel kann man auf den unterschiedlichen Devices ausführen, beispielsweise als App für den Windows Desktop, als Web-App für den Browser und als Mobile-App für Android und iOS auf einem physischen Device beziehungsweise Simulator.

Wichtig: UI und Geschäftslogik bleiben überall identisch, nur das Host-Projekt beziehungsweise die Zielplattform ändert sich.

Beispiel: Erweiterung

Nachdem das minimale To-do-Beispiel fertig ist, betrachten wir nun das etwas umfangreichere, offizielle To-do-Referenzbeispiel aus dem Uno.Samples-Repository. Diese To-do-App präsentiert sich in einem modernen Look (Material Design 3) und bietet alle grundlegenden Funktionen einer Aufgabenverwaltung, das heißt Nutzer-Login, Anlage von Aufgaben mit Fälligkeitsdatum und eine Erinnerungsfunktion. Die Anwendung ist vollständig plattformübergreifend ausgelegt. Das identische UI läuft als WebAssembly-App im Browser, auf dem Desktop und als App auf Mobilgeräten.

Das Projekt folgt dem klassischen MVVM-Pattern: Die Ordnerstruktur trennt Models, ViewModels und Views (XAML-Pages). In den Dateien, welche die Views enthalten, etwa TaskListPage.xaml oder WelcomePage.xaml, werden die Bindings zu den ViewModels definiert. Die Anwendung verwendet einen zentralen Navigationsservice zum Wechseln zwischen Seiten – etwa von der Aufgabenliste zur Detail- oder Einstellungsseite.

Die Hauptseite zeigt eine Liste aller To-do-Einträge an. Per Command-Bindung können Nutzer neue Aufgaben hinzufügen oder vorhandene bearbeiten und löschen. Zum Beispiel wird ein Löschen-Command im ViewModel wie folgt definiert:

 

public ICommand DeleteTaskCommand => new RelayCommand<TaskItem>(task =>
 {
   _tasks.Remove(task); // entfernt die Aufgabe aus der Liste
 });
 
 

 

Dieses Command wird im XAML-Code an einen Button gebunden, sodass ein Listeneintrag gelöscht werden kann. Damit weist der Button das Command an, das jeweils ausgewählte TaskItem zu entfernen. Ähnlich funktionieren Befehle zum Speichern oder Aktualisieren von Aufgaben.

Die UI-Elemente sind über XAML-Bindings direkt mit den Eigenschaften im ViewModel verknüpft. Als Beispiel dient hier ein einfaches Textfeld für eine neue Aufgabe, mit bidirektionaler Bindung:

 

<TextBox Text="{Binding NewTaskTitle, Mode=TwoWay}" PlaceholderText="Neue Aufgabe..." />

 

Hier bindet NewTaskTitle eine ViewModel-Eigenschaft (INotifyPropertyChanged), sodass Änderungen im UI automatisch ins ViewModel übernommen werden und umgekehrt. Die Aufgabenliste (ListView) bindet an eine ObservableCollection:

 

<ListView ItemsSource="{x:Bind ViewModel.Tasks}">
   <ListView.ItemTemplate>
     <DataTemplate x:DataType="models:TaskItem">
       <TextBlock Text="{x:Bind Title}" />
     </DataTemplate>
   </ListView.ItemTemplate>
 </ListView>
 
 

 

Die Verwendung von Bindings ermöglicht es, Datenströme einfach zu verknüpfen. So aktualisiert sich die Anzeige automatisch, wenn das ViewModel die Aufgabendaten ändert. Die App nutzt die Navigation, um zum Beispiel nach dem Login zur Aufgabenliste zu gelangen oder um von der Liste zur Detailansicht einer Aufgabe zu springen. Zum Beispiel ruft Navigate("TaskDetailPage", task.Id) eine neue Seite auf (TaskDetailPage), übergibt dabei die ID der ausgewählten Aufgabe und zeigt deren Details an. Dieses Muster trennt die Navigation von der UI, da der ViewModel-Befehl unabhängig von der View die Methode ausführt.

Die Beispiel-App wird im Web als WebAssembly-Anwendung geladen, auf Desktop-Betriebssystemen wie Windows oder macOS läuft sie als native Applikation und auf Android/ iOS nutzt sie die nativen Steuerelemente (Bild 6). 

Beispiel-App (ToDo, extended) im Web, auf dem Desktop und als mobile App (Bild 6)

Beispiel-App (ToDo, extended) im Web, auf dem Desktop und als mobile App (Bild 6)

© Autor

Dank adaptiver Layouts und responsiver XAML-Elemente passen sich die UI-Controls automatisch an Touch- oder Maussteuerung, unterschiedliche Bildschirmgrößen und Auflösungen an. In allen Umgebungen zeigt die Anwendung eine moderne, aufgeräumte Oberfläche – etwa ListViews, Buttons und Eingabefelder, die ein plattformspezifisches Look and Feel sicherstellen.

Dieses erweiterte Beispiel ist bereits technisch anspruchsvoll, motiviert aber zum Ausprobieren: Es zeigt, wie man mit der Uno Platform Navigation, Zwei-Wege-Datenbindung, Commands und plattformübergreifende Funktionen in einer realistischen App umsetzt.

Fazit und Ausblick

Die Uno Platform zeigt bereits im ersten Schritt, wie sich mit vertrauter WinUI-/XAML-Syntax plattformübergreifende UIs entwickeln lassen. Architektur, UX-Konzepte, Tooling und ein starkes Ökosystem schaffen die Basis für produktive Workflows, die Desktop, Mobile und Web gleichermaßen unterstützen. Das Beispiel verdeutlicht, wie schon mit wenigen Zeilen Code eine App entsteht, die auf allen Zielsystemen lauffähig ist.Weitere Artikel werden sich mit den Layoutsystemen der Uno Platform beschäftigen und zeigen, wie man mit Grids, StackPanels und flexiblen Containern responsive Oberflächen gestalten kann, siehe Kasten „Artikelserie: UI-Gestaltung mit der Uno Platform“.

Neueste Beiträge

Vor dem Prompt ist nach dem Prompt - KI für KMU, Teil 2
Wie bereitet man Anfragen an Large Language Models bestmöglich vor?
7 Minuten
13. Nov 2025
Builder meets Faker - Testdata-Builder, Teil 2
Wer viele Testdaten braucht, liebt Bogus: Die Library erzeugt auf Knopfdruck realistische Daten und geht mit dem Builder-Pattern eine perfekte Kombination ein.
6 Minuten
12. Nov 2025
DDC hakt nach: Hör auf, Dich über Verbindungsstrings zu ärgern
Die App läuft lokal wie geschmiert, aber sobald Backend-Services ins Spiel kommen, stottert die Maschine. Connection Strings, die nicht wollen. Emulator-Konfigurationen, die nerven. Johan Smarius erklärt im Interview und auf der .NET Developer Conference 2025, wie es anders - und viel besser geht.
4 Minuten
10. Nov 2025

Das könnte Dich auch interessieren

DDC hakt nach: Steiniger Weg von WPF zu Avalonia?
WPF hat ausgedient? Wer ein modernes User Interface über alle Plattformen hinweg entwickeln will, kommt an Avalonia UI kaum vorbei. Doch was taugt Avalonia im Vergleich zu MAUI oder Blazor? Dieses Interview räumt mit Mythen auf – und zeigt, worauf sich Entwickler:innen einstellen müssen.
5 Minuten
13. Okt 2025
Das Tempo bleibt ordentlich - Neuerungen in Blazor 10.0, TEIL 2
Auch beim Monitoring, dem QuickGrid-Steuerelement und der C#-JavaScript-Interoperabilität bietet Blazor 10.0 einige Verbesserungen.
20 Minuten
React, Angular und Vue.js: Eine Gegenüberstellung von Frontend-Frameworks - Web
Moderne JavaScript-Frameworks sorgen für höchste Effizienz in der Webentwicklung. Doch welches Framework eignet sich für welchen Einsatz?
10 Minuten
29. Feb 2024
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige