{"id":2997,"date":"2023-12-09T18:30:10","date_gmt":"2023-12-09T17:30:10","guid":{"rendered":"https:\/\/www.art-events.de\/weblog\/?p=2997"},"modified":"2023-12-12T11:39:09","modified_gmt":"2023-12-12T10:39:09","slug":"android-programmierung-mit-c-und-dot-net-maui-teil-1-einstieg","status":"publish","type":"post","link":"https:\/\/www.art-events.de\/weblog\/android-programmierung-mit-c-und-dot-net-maui-teil-1-einstieg\/","title":{"rendered":"Android Programmierung mit C# und DOT NET MAUI. Teil 1. Einstieg"},"content":{"rendered":"<p>Einf\u00fchrung in Programmierung C# mit DOT Net MAUI.<\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc1728_4174826217\"><\/a>Visual Studio, C# und DOT Net MAUI<\/strong><\/h3>\n<p>Wer schon mal dar\u00fcber nachgedacht hat, ein eigenes Programm zu schreiben, ist sicher irgendwie \u00fcber <a href=\"https:\/\/visualstudio.microsoft.com\/de\/\" target=\"_blank\" rel=\"noopener\">Microsoft Visual Studio<\/a> gestolpert. Eine leistungsf\u00e4hige Oberfl\u00e4che zur Softwareentwicklung mit Unterst\u00fctzung diverser Programmiersprachen. Wer dazu gerne f\u00fcr Windows Anwendungen entwickelt, wird fr\u00fcher oder sp\u00e4ter Bekanntschaft mit C# schlie\u00dfen, eine recht m\u00e4chtige, objektorientierte Programmiersprache, die Microsoft inzwischen gut etabliert hat. Ich selbst entwickele seit vielen Jahren Windows Anwendungen unter C# und sowohl meine Kunden als auch meine Person sind mit Ergebnis und Aufwand recht zufrieden.<\/p>\n<p>Wenn es hingegen um Apps f\u00fcr Android Smartphones geht, setze ich auf das Android Studio von Google. Doch wie sch\u00f6n w\u00e4re es, wenn man auch f\u00fcr Smartphone Apps unter einer bekannten Programmiersprache und Entwicklungsumgebung schreiben k\u00f6nnte?<\/p>\n<p>Die Antwort lautet: GEHT! Mit DOT.NET MAUI (nachstehend .NET MAUI) bietet sich eine elegante L\u00f6sung, um Programme plattform\u00fcbergreifend unter C# zu entwickeln: f\u00fcr Android oder Apple IOS Ger\u00e4te oder f\u00fcr x86 Windows. <a href=\"https:\/\/learn.microsoft.com\/de-de\/dotnet\/maui\/what-is-maui?view=net-maui-8.0\" target=\"_blank\" rel=\"noopener\">Lesetipp: Microsoft &#8211; was ist .NET Maui<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium\" src=\"https:\/\/www.terminal-systems.de\/images\/231212-maui.jpg\" width=\"1047\" height=\"500\" \/><\/p>\n<p>Basis ist das Microsoft Visual Studio mit der .NET MAUI Erweiterung. Beides ist kostenfrei verf\u00fcgbar und kann(MS Visual Studio) direkt von der Microsoft Webseite geladen werden.<\/p>\n<p>Eine kleine Einschr\u00e4nkung: F\u00fcr die Entwicklung mit Apple IOS ben\u00f6tige ich einen Mac Computer oder ein Apple iPhone. Da ich beides nicht habe, interessiert mich IOS nicht und ich beschr\u00e4nke mich in der Entwicklung auf Android und x86 Windows.<\/p>\n<p>Wie das Ganz geht, werde ich hier erl\u00e4utern. Doch vorweg noch mal der Hinweis: Dieses ist zwar ein Grundkurs, aber ihr solltet schon etwas Grundlagenwissen haben und evtl auch schon erste Erfahrungen mit dem Visual Studio und Programmierung in C# haben. Ihr solltet auch wissen, was eine Variable ist, und dass man Zahlen in Integer und Texte in String Variablen speichert etc. Wenn euch solche Basics noch fremd sind \u2013 empfehle ich ein Grundlagenbuch f\u00fcr C#, um diese Dinge zu erlernen.<\/p>\n<p><span style=\"color: #339966;\"><strong>Hinweis: Das YouTube Video zum Beitrag findet sich am Ende dieser Seite!<\/strong><\/span><\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc321_116626896\"><\/a>Der Start: Projekt anlegen<\/strong><\/h3>\n<p>Die Ausgangsvoraussetzung: Microsoft Visual Studio 2022 und .NET MAUI installiert und gestartet. Projekt anlegen. .NET MAUI als Projektvorlage w\u00e4hlen.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1001\" height=\"409\" class=\"wp-image-3016\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-1-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-1-1.png 1001w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-1-1-300x123.png 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-1-1-768x314.png 768w\" sizes=\"auto, (max-width: 1001px) 100vw, 1001px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"474\" class=\"wp-image-3017\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-2-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-2-1.png 768w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-2-1-300x185.png 300w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/p>\n<p>Was eine gute Entwicklungsumgebung ausmacht: Um das Erstellen des Projektes k\u00fcmmert sich das Studio. Wenn alles geladen ist, starte ich in der Arbeitsoberfl\u00e4che. F\u00fcr das erste Grundverst\u00e4ndnis in der .NET MAUI Welt, muss ich mir vier wichtige Dateigruppen im Projektmappen Explorer ansehen:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"354\" height=\"336\" class=\"wp-image-3018\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-3-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-3-1.png 354w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-3-1-300x285.png 300w\" sizes=\"auto, (max-width: 354px) 100vw, 354px\" \/><\/p>\n<p><strong>MauiProgram.CS<\/strong><\/p>\n<p>Bootstrap File. Hier ist der Einstiegs Punkt f\u00fcr die Anwendung.<\/p>\n<p><strong>App.XAML \/ App.XAML.CS<\/strong><\/p>\n<p>Hier kommen Farben, Ressourcen und anderes hinein.<\/p>\n<p><strong>AppShell. XAML \/ AppShell.XAML.CS<\/strong><\/p>\n<p>Hierarchie Datei der App. Hier werden die verschiedenen Displays (Android: Activities) der App eingetragen und lassen sich dann in einem Men\u00fc starten.<\/p>\n<p><strong>MainPage. XAML \/ MainPage.XAML.CS<\/strong><\/p>\n<p>Ein erstes Display (Android: erste Activity) mit dem XAML Code f\u00fcr Layout und dem C# Code f\u00fcr die Aktionen.<\/p>\n<p>Es ist wenig \u00fcberraschend: die XAML Dateien enthalten den XAML Code, meistens mit Layout Beschreibungen. Die CS Dateien den C# Programmcode dahinter &#8211; ich nenne das mal Code-Behind.<\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc323_116626896\"><\/a>Das Layout &#8211; MainPage.XAML<\/strong><\/h3>\n<p>Die im Visual Studio jetzt standardm\u00e4\u00dfig angelegte MainPage Applikation besteht aus einem Display und ist eine Datei mit Text, einem Bild einem Button, der bei jeder Bet\u00e4tigung hoch gez\u00e4hlt wird. XAML wird verwendet, um die einzelnen Steuerelemente im Layout zu beschreiben.<\/p>\n<pre>&lt;ScrollView&gt;\r\n  &lt;VerticalStackLayout\r\n    Spacing=\"25\"\r\n    Padding=\"30,0\"\r\n    VerticalOptions=\"Center\"&gt;\r\n  &lt;Image\r\n    Source=\"dotnet_bot.png\"\r\n    SemanticProperties.Description=\"Cute dot net bot waving hi to you!\"\r\n    HeightRequest=\"200\"\r\n    HorizontalOptions=\"Center\" \/&gt;\r\n  &lt;Label\r\n    Text=\"Hello, World!\"\r\n    SemanticProperties.HeadingLevel=\"Level1\"\r\n    FontSize=\"32\"\r\n    HorizontalOptions=\"Center\" \/&gt;\r\n  &lt;Label\r\n    Text=\"Welcome to .NET Multi-platform App UI\"\r\n    SemanticProperties.HeadingLevel=\"Level2\"\r\n    SemanticProperties.Description=\"Welcome to dot net Multi platform App U I\"\r\n    FontSize=\"18\"\r\n    HorizontalOptions=\"Center\" \/&gt;\r\n  &lt;Button\r\n    x:Name=\"CounterBtn\"\r\n    Text=\"Click me\"\r\n    SemanticProperties.Hint=\"Counts the number of times you click\"\r\n    Clicked=\"OnCounterClicked\"\r\n    HorizontalOptions=\"Center\" \/&gt;\r\n  &lt;\/VerticalStackLayout&gt;\r\n&lt;\/ScrollView&gt;<\/pre>\n<p>Mein erstes Display tr\u00e4gt also den Namen MainPage. Die Datei MainPage.XAML beinhaltet die Layout Elemente. Gekapselt in einer ScrollView: Bild, 2x Label mit verschiedenen Darstellungen und 1x Button. Button Aktion wird \u00fcber Clicked ausgel\u00f6st. Die Aktionen stehen in der CS Datei.<\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc325_116626896\"><\/a>Der C# Programmcode &#8211; MainPage.xaml.CS<\/strong><\/h3>\n<p>Die XAML.CS Datei enth\u00e4lt den C# Programmcode. Im vorliegenden Fall einige vordefinierte Elemente. U.a. einen Counter, der mit jeder Button Bet\u00e4tigung hoch gez\u00e4hlt wird. Anschlie\u00dfend wird ein Text ausgegeben.<\/p>\n<pre>namespace MauiApp2;\r\npublic partial class MainPage : ContentPage\r\n\r\n{\r\n  int count = 0;\r\n\r\n  public MainPage()\r\n  {\r\n    InitializeComponent();\r\n  }\r\n\r\n  private void OnCounterClicked(object sender, EventArgs e)\r\n  {\r\n    count++;\r\n    if (count == 1)\r\n      CounterBtn.Text = $\"Clicked {count} time\";\r\n    else\r\n      CounterBtn.Text = $\"Clicked {count} times\";\r\n    SemanticScreenReader.Announce(CounterBtn.Text);\r\n  }\r\n}<\/pre>\n<p>Nun k\u00f6nnen weitere Activities hinzugef\u00fcgt oder die MainPage Activitiy ge\u00e4ndert werden. Doch bevor ich das tue, will ich einen kleinen Exkurs einschieben:<\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc327_116626896\"><\/a>Meine Programme plappern: Debug Meldungen zur Laufzeit<\/strong><\/h3>\n<p>In meiner Programmierung immer gerne gesehen: ich will zur Laufzeit irgendwelche Werte oder Variablen sehen, um das Programmverhalten zu pr\u00fcfen.\u00a0In gewohnter Form bietet mit DOT NET MAUI hierf\u00fcr einfache L\u00f6sungen etwas ins Ausgabefenster von Visual Studio zu bekommen:<\/p>\n<pre>System.Diagnostics.Debug.WriteLine(\"Button Clear used\");<\/pre>\n<p>oder<\/p>\n<pre>Console.WriteLine(\"Etwas ist geschehen!\");<\/pre>\n<p>Beides sieht im Ausgabefenster dann so aus:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"707\" height=\"202\" class=\"wp-image-3019\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-4-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-4-1.png 707w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-4-1-300x86.png 300w\" sizes=\"auto, (max-width: 707px) 100vw, 707px\" \/><\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc332_1301169580\"><\/a>Infos f\u00fcr den Benutzer &#8211; Toast Meldungen<\/strong><\/h3>\n<p>Toast Meldungen unter Android sind kleine Sprechblasen in denen Hinweistexte f\u00fcr den Benutzer angezeigt werden. Unter Windows gibt es die auch. Dort werden sie in der Ecke der Taskleiste angezeigt. Merkmal von Toast Meldungen: Sie bleiben nur f\u00fcr eine kurze Zeit im Display und verschwinden dann in der Regel selbst\u00e4ndig. Die Dinger finde ich ungemein praktisch, wenn ich dem Benutzer irgendwelche Informationen liefern will, z.b. dass ein Speichervorgang abgeschlossen wurde.<\/p>\n<p>Wichtig zu wissen: eine Toast Meldung h\u00e4lt das Programm NICHT an, sondern die Software l\u00e4uft in der Zwischenzeit weiter. Sie sind damit nicht vergleichbar mit Messageboxen unter Windows, bei denen die Anwendung solange stoppt, bis der Benutzer eine Taste bet\u00e4tigt und die Meldung manuell weg klickt! Das ist an dieser Stelle noch nicht wirklich wichtig. Es erlangt aber dann Bedeutung, wenn Ihr Abfragen bastelt wie: Daten l\u00f6schen Ja \/ Nein. Wenn das Programm schon weiter l\u00e4uft, w\u00e4hrend die Abfrage dargestellt wird und Ihr die Daten emsig in den Papierkorb haut, bevor der Benutzer eine Taste bet\u00e4tigt hat, ist es irgendwie doof. Toast Meldungen halten die Software also nicht an, sondern sind nur Infotexte. Und es darf in meiner Software auch nichts Gravierendes geschehen, wenn der Benutzer den Infotext verpasst!<\/p>\n<h3><strong><a id=\"post-2997-__RefHeading___Toc334_1301169580\"><\/a>Community Package<\/strong><\/h3>\n<p>Damit wir Toast Meldungen unter DOT Net MAUI sehen k\u00f6nnen, muss zuerst das Community Package mit allerlei n\u00fctzlichen Android Features geladen und in der App installiert werden. Die MS Dokumentation befindet sich hier:<\/p>\n<p><a href=\"https:\/\/learn.microsoft.com\/de-de\/dotnet\/communitytoolkit\/maui\/get-started?tabs=CommunityToolkitMaui\" target=\"_blank\" rel=\"noopener\">https:\/\/learn.microsoft.com\/de-de\/dotnet\/communitytoolkit\/maui\/get-started?tabs=CommunityToolkitMaui<\/a><\/p>\n<p><strong>Die Schritte:<\/strong><\/p>\n<p>Zuerst via NuGet-Pakete verwalten das Community Package laden und installieren!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"511\" class=\"wp-image-3020\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-5-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-5-1.png 584w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-5-1-300x263.png 300w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"246\" class=\"wp-image-3021\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-6-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-6-1.png 1000w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-6-1-300x74.png 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-6-1-768x189.png 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p><strong>Gezielt nach Community Toolkit . MAUI suchen!<\/strong><\/p>\n<p>Wichtig: Bei der Wahl der Version muss ich ein Paket ausw\u00e4hlen, das in den Abh\u00e4ngigkeiten zum aktuell verwendeten .NET meines Projektes passt. Die .NET Version meines Projektes habe ich beim Erstellen des Projektes angegeben \u2013 in meinen Fall war das .NET 7. Aso w\u00e4hle ich ein CommunityToolkit.MAUI das .NET 7 supported! Standardm\u00e4\u00dfig wird mir gerade ein Package angeboten, die allerdings nur .NET 8 unterst\u00fctzt. Beim Versuch das zu installieren, gibt es haufenweise Fehlermeldungen!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"547\" height=\"486\" class=\"wp-image-3022\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-7-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-7-1.png 547w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-7-1-300x267.png 300w\" sizes=\"auto, (max-width: 547px) 100vw, 547px\" \/><\/p>\n<p>Wenn das Paket installiert wurde: anschlie\u00dfend in Maui.Programm.cs das Paket eintragen:<\/p>\n<p>&#8211; in der using Zeile2<\/p>\n<p>&#8211; in Zeile13: .UseMauCommunityToolkit()<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"745\" height=\"398\" class=\"wp-image-3023\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-8-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-8-1.png 745w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-8-1-300x160.png 300w\" sizes=\"auto, (max-width: 745px) 100vw, 745px\" \/><\/p>\n<p>Jetzt kann ich in meiner Anwendung eine Toast Meldung f\u00fcr den Benutzer aufrufen, wenn der Button gedr\u00fcckt wird. Allerdings muss die Methode auf async gesetzt werden. Der Aufruf im einfachsten Fall:<\/p>\n<pre>async private void SavebtnClicked(object sender, EventArgs e)\r\n{\r\n  \/\/ Save the file.\r\n  File.WriteAllText(_fileName, TextEditor.Text);\r\n  await Toast.Make(\"Gespeichert\").Show();\r\n}<\/pre>\n<h3><a id=\"post-2997-__RefHeading___Toc839_1781186391\"><\/a><strong>Ein weiteres Display: Mini Mini Editor<\/strong><\/h3>\n<p>Ich will die erste App erweitern. In Anlehnung an die Microsoft Dokumentation zum .NET MAUI bastele ich eine kleine Anwendung um einen Mini Editor zu schaffen, mit dem ich Text eingeben und speichern kann. \u00dcber Projektmappen Explorer, Projektname \u2013 Rechte Maustaste w\u00e4hle ich Hinzuf\u00fcgen \u2013 Neues Element:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"942\" height=\"445\" class=\"wp-image-3024\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-9-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-9-1.png 942w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-9-1-300x142.png 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-9-1-768x363.png 768w\" sizes=\"auto, (max-width: 942px) 100vw, 942px\" \/><\/p>\n<p>Ich w\u00e4hle eine XAML Content Page und nennen sie MiniEditor.XAML. Die XAML und die zugeh\u00f6rige CS Datei werden im Projektmappen Explorer angelegt und angezeigt:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"295\" height=\"336\" class=\"wp-image-3025\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-10-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-10-1.png 295w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-10-1-263x300.png 263w\" sizes=\"auto, (max-width: 295px) 100vw, 295px\" \/><\/p>\n<h3>Die Layout Datei MiniEditor.XAML<\/h3>\n<p>In der XAML Datei hinterlege ich ein Label als \u00dcberschrift, einen Editor als Eingabeelement und vier Buttons nebeneinander in einem Grid. Die Buttons werden \u00fcber die Eigenschaft CLICKED ausgewertet. Der Code hierf\u00fcr wird in der CS Datei eingetragen.<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;ContentPage xmlns=\"http:\/\/schemas.microsoft.com\/dotnet\/2021\/maui\"\r\n  xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n  x:Class=\"MauiApp1.MiniEditor\"\r\n  Title=\"MiniEditor\"&gt;\r\n\r\n  &lt;VerticalStackLayout&gt;\r\n    &lt;Label\r\n      Text=\"Mein kleiner .NET MAUI Editor\"\r\n      VerticalOptions=\"Center\"\r\n      HorizontalOptions=\"Center\" \/&gt;\r\n\r\n    &lt;Editor x:Name=\"TextEditor\"\r\n      Placeholder=\"Namen eingeben\"\r\n      HeightRequest=\"200\" \/&gt;\r\n\r\n    &lt;Grid ColumnDefinitions=\"*,*,*,*\" ColumnSpacing=\"4\"&gt;\r\n      &lt;Button Text=\"Save\"\r\n        Clicked=\"SavebtnClicked\"\/&gt;\r\n  \r\n      &lt;Button Grid.Column=\"1\"\r\n        Text=\"Clear\"\r\n        Clicked=\"ClearbtnClicked\"\r\n      \/&gt;\r\n\r\n      &lt;Button Grid.Column=\"2\"\r\n        Text=\"Destroy\"\r\n        Clicked=\"DestroybtnClicked\"\/&gt;\r\n\r\n      &lt;Button Grid.Column=\"3\"\r\n        Text=\"Load\"\r\n        Clicked=\"LoadbtnClicked\"\/&gt;\r\n    &lt;\/Grid&gt;\r\n  &lt;\/VerticalStackLayout&gt;\r\n&lt;\/ContentPage&gt;<\/pre>\n<h3><a id=\"post-2997-__RefHeading___Toc843_1781186391\"><\/a><strong>Die CS Datei<\/strong><\/h3>\n<p>Die CS Datei enth\u00e4lt die Click Methoden f\u00fcr die vier Buttons. In allen F\u00e4llen werden einfach verst\u00e4ndliche Standardroutinen aufgerufen, so dass ich mir deren Erkl\u00e4rung hier erspare.<\/p>\n<pre>using CommunityToolkit.Maui.Alerts;\r\nnamespace MauiApp1;\r\n\r\n\/\/-------------------------------------------------------------------------------\u00b4\u00b4\r\n\r\npublic partial class MiniEditor : ContentPage\r\n{\r\n  string _fileName = Path.Combine(FileSystem.AppDataDirectory, \"MiniEditor.txt\");\r\n\r\n  public MiniEditor()\r\n  {\r\n    InitializeComponent();\r\n  }\r\n\r\n\/\/-------------------------------------------------------------------------------\u00b4\u00b4\r\nprivate void ClearbtnClicked(object sender, EventArgs e)\r\n{\r\n  TextEditor.Text = string.Empty;\r\n}\r\n\r\n\/\/-------------------------------------------------------------------------------\u00b4\u00b4\r\nasync private void SavebtnClicked(object sender, EventArgs e)\r\n{\r\n  \/\/ Save the file.\r\n  File.WriteAllText(_fileName, TextEditor.Text);\r\n  await Toast.Make(\"Gespeichert\").Show();\r\n}\r\n\r\n\/\/-------------------------------------------------------------------------------\u00b4\u00b4\r\nprivate void DestroybtnClicked(object sender, EventArgs e)\r\n{\r\n  \/\/ Delete the file.\r\n  if (File.Exists(_fileName))\r\n    File.Delete(_fileName);\r\n  TextEditor.Text = string.Empty;\r\n}\r\n\r\n\/\/-------------------------------------------------------------------------------\u00b4\u00b4\r\nprivate void LoadbtnClicked(object sender, EventArgs e)\r\n{\r\n  if (File.Exists(_fileName))\r\n    TextEditor.Text = File.ReadAllText(_fileName);\r\n\r\n  Console.WriteLine(\"Etwas ist geschehen!\");\r\n\r\n  }\r\n}<\/pre>\n<h3><a id=\"post-2997-__RefHeading___Toc845_1781186391\"><\/a><strong>Im Men\u00fc eintragen: AppShell.XAML<\/strong><\/h3>\n<p>Damit das Ganze mit beiden Displays sichtbar ist, erweitere ich die AppShell.XAML Datei um eine TabBar und trage beide Displays dort ein. Die TabBar schenkt mir ein Men\u00fc, aus dem heraus ich beide Displays starten kann.<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"UTF-8\" ?&gt;\r\n&lt;Shell\r\n  x:Class=\"MauiApp1.AppShell\"\r\n   xmlns=\"http:\/\/schemas.microsoft.com\/dotnet\/2021\/maui\"\r\n   xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n   xmlns:local=\"clr-namespace:MauiApp1\"\r\n   Shell.FlyoutBehavior=\"Disabled\"&gt;\r\n   &lt;TabBar&gt;\r\n      &lt;ShellContent\r\n        Title=\"Home\"\r\n        ContentTemplate=\"{DataTemplate local:MainPage}\"\r\n        Route=\"MainPage\" \/&gt;\r\n\r\n    ShellContent\r\n        Title=\"Mini Editor\"\r\n        ContentTemplate=\"{DataTemplate local:MiniEditor}\"&gt;\r\n    &lt;\/ShellContent&gt;\r\n  &lt;\/TabBar&gt;\r\n&lt;\/Shell&gt;<\/pre>\n<h3><a id=\"post-2997-__RefHeading___Toc847_1781186391\"><\/a><strong>App ausprobieren \u2013 im Android Simulator<\/strong><\/h3>\n<h3><a id=\"post-2997-__RefHeading___Toc1106_1781186391\"><\/a><strong>Ger\u00e4te Manager \u00f6ffnen \u2013 Device starten<\/strong><\/h3>\n<p>Ich \u00f6ffne den Ger\u00e4te Manager und starte ein bereits angelegtes Ger\u00e4t, in diesem Fall das Pixel 7 mit API 33.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"222\" height=\"107\" class=\"wp-image-3026\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-11-1.png\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1010\" height=\"343\" class=\"wp-image-3027\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-12-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-12-1.png 1010w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-12-1-300x102.png 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-12-1-768x261.png 768w\" sizes=\"auto, (max-width: 1010px) 100vw, 1010px\" \/><\/p>\n<p>Anschlie\u00dfend lasse ich mir den Debug Build bauen und auf dem ausgew\u00e4hlten Device laufen:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"522\" height=\"118\" class=\"wp-image-3028\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-13-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-13-1.png 522w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-13-1-300x68.png 300w\" sizes=\"auto, (max-width: 522px) 100vw, 522px\" \/><\/p>\n<p>Das Ganze schaut dann so aus und wir haben ein Auswahlmen\u00fc bekommen in der ich zwischen den beiden Screens hin- und herschalten kann. Im Fall von Android befindet sich das Men\u00fc unten am Displayrand.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"237\" height=\"500\" class=\"wp-image-3029\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-14-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-14-1.png 237w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-14-1-142x300.png 142w\" sizes=\"auto, (max-width: 237px) 100vw, 237px\" \/> <img loading=\"lazy\" decoding=\"async\" width=\"237\" height=\"500\" class=\"wp-image-3030\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-15-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-15-1.png 237w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-15-1-142x300.png 142w\" sizes=\"auto, (max-width: 237px) 100vw, 237px\" \/><\/p>\n<h3><a id=\"post-2997-__RefHeading___Toc1108_1781186391\"><\/a><strong>App ausprobieren \u2013 unter Windows<\/strong><\/h3>\n<p>Um zu sehen, wie die App unter Windows aussieht, \u00e4ndere ich das Zielsystem auf Windows Machine und starte den Debug Vorgang.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"128\" class=\"wp-image-3031\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-16-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-16-1.png 473w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-16-1-300x81.png 300w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><\/p>\n<p>Auch hier erhalte ich zwei Displays und das Men\u00fc steht dieses Mail oben. Ich kann die App unter x86 Windows genauso bedienen wie auf dem Android Simulator.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"650\" height=\"343\" class=\"wp-image-3032\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-17-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-17-1.png 650w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-17-1-300x158.png 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"650\" height=\"343\" class=\"wp-image-3033\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-18-1.png\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-18-1.png 650w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2023\/12\/word-image-2997-18-1-300x158.png 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<h3><a id=\"post-2997-__RefHeading___Toc374_2555633834\"><\/a><strong>Steuerelemente und M\u00f6glichkeiten<\/strong><\/h3>\n<p>Steuerelemente werden unter .NET MAUI nicht Controls, sondern Views genannt. Hier nur in der \u00dcbersicht. Weitere Details werde ich nach Bedarf nachtragen.<\/p>\n<p><strong>Gr\u00f6\u00dfe und Position<\/strong><\/p>\n<p>Werden mit HeightRequest und WidthRequest angegeben!<\/p>\n<p><strong>Zugriff<\/strong><\/p>\n<p>Ben\u00f6tigt x:Name = \u201exxxxx\u201c. Dann Zugriff \u00fcber xxxxx m\u00f6glich!<\/p>\n<p><strong>Label<\/strong><\/p>\n<p>Dient der Darstellung von Text. Kann mit diversen Attributen versehen werden. Einfaches HTML ist m\u00f6glich. F\u00fcr komplexes HTML aber WebView verwenden!<\/p>\n<p><strong>WebView<\/strong><\/p>\n<p>Kann komplette HTML Dokumente ausgeben<\/p>\n<p><strong>ActivityIndicator<\/strong><\/p>\n<p>Info f\u00fcr den Benutzer, das etwas geschieht. Beispiel: ActivityIndicator1.IsRunning = true;<\/p>\n<p><strong>ProgressBar<\/strong><\/p>\n<p>Info f\u00fcr den Benutzer \u00fcber einen laufenden Vorgang.<\/p>\n<p><strong>Border \/ Shadow \/ Shapes<\/strong><\/p>\n<p>Rahmen um ein View. Schatten. Diverse Formen.<\/p>\n<p><strong>Texteingaben Entry \/ Editor<\/strong><\/p>\n<p>Entry einzeilig. Editor mehrzeilige Eingaben.<\/p>\n<p><strong>Button<\/strong><\/p>\n<p>Abfrage \u00fcber Eigenschaft CLICKED im xaml Code oder im Code Behind durch Konstruktor.<\/p>\n<p>Dazu die \u00fcblichen Verd\u00e4chtigen:<\/p>\n<p>RadioButton, CheckBox, Switch, Picker mit DatePicker \/ TimePicker<\/p>\n<h3><a id=\"post-2997-__RefHeading___Toc415_4100410144\"><\/a><strong>Die Sache mit der Datenbindung<\/strong><\/h3>\n<p>In der Standardprogrammierung werden Im XAML Code die Steuerelemente untergebracht, in der CS Datei als Code-Behind werden die Ereignisse definiert. Dieses Verfahren kann bei umfangreichen Programmen un\u00fcbersichtlich werden, so dass man ein Model-View-View Modell und eine Datenbindung einsetzt. Dieses Modell besteht aus den Komponenten:<\/p>\n<p><strong>View<\/strong><\/p>\n<p>In der View werden die reinen Steuerelemente untergebracht<\/p>\n<p><strong>ViewModel<\/strong><\/p>\n<p>Hier werden die Daten f\u00fcr die View bereitgestellt<\/p>\n<p><strong>Model<\/strong><\/p>\n<p>Kapselt und verarbeitet die Daten. Hat aber keine Kenntnis von der View oder vom ViewModel.<\/p>\n<p>Umfangreiche Dokumentation findet sich im Internet. Ich werde mich hier zuerst einmal auf Apps mit XAML und Code-Behind CS Dateien beschr\u00e4nken und die Datenbindung in einem sp\u00e4teren Teil vertiefen.<\/p>\n<hr \/>\n<p>Das Video zum Thema:<\/p>\n<p><iframe loading=\"lazy\" title=\"Android Programmierung mit Microsoft Visual Studio, C# und DOT NET MAUI. Teil1. Einstieg.\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/cLJR6QbTkEc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<hr \/>\n<p><a href=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/06\/20080607hjwx-204.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2104\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/06\/20080607hjwx-204.jpg\" alt=\"\" width=\"204\" height=\"153\" \/><\/a><\/p>\n<p>Text und Entwurf. (c)\u00a0<a href=\"https:\/\/www.terminal-systems.de\/\" target=\"_blank\" rel=\"noopener\">AE SYSTEME Testcenter<\/a>, Hans-J. Walter<br \/>\nHans-J. Walter ist Programmierer f\u00fcr Windows DOT.NET \/ C# und Android und als eingetragener, unabh\u00e4ngiger Journalist verantwortlich f\u00fcr Fachberichte und Schulungstexte \u00fcber Technik u. Entwicklung.\u00a0<a href=\"mailto:hjw@terminal-systems.de\">hjw@terminal-systems.de<\/a><\/p>\n<p><em>F\u00fcr diese und alle nachfolgenden Seiten gilt ebenso der obligatorische Hinweis: Alle Angaben ohne Gew\u00e4hr. Bilder und Codes zeigen Beispiele. Diese Beschreibung bezieht sich auf unsere Installation und stellt keine Bewertung der verwendeten Techniken da. Fehler und Irrt\u00fcmer vorbehalten!<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Einf\u00fchrung in Programmierung C# mit DOT Net MAUI. Visual Studio, C# und DOT Net MAUI Wer schon mal dar\u00fcber nachgedacht hat, ein eigenes Programm zu schreiben, ist sicher irgendwie \u00fcber Microsoft Visual Studio gestolpert. Eine leistungsf\u00e4hige Oberfl\u00e4che zur Softwareentwicklung mit Unterst\u00fctzung diverser Programmiersprachen. Wer dazu gerne f\u00fcr Windows Anwendungen entwickelt, wird fr\u00fcher oder sp\u00e4ter Bekanntschaft [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,34,36],"tags":[62,56,68,67,63,64,65,57,66],"class_list":["post-2997","post","type-post","status-publish","format-standard","hentry","category-android","category-programmierung","category-windows-linux","tag-net-maui","tag-android","tag-c-sharp","tag-c","tag-dot-net","tag-maui","tag-microsoft","tag-programmierung","tag-visual-studio","entry"],"_links":{"self":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts\/2997","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/comments?post=2997"}],"version-history":[{"count":0,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts\/2997\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/media?parent=2997"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/categories?post=2997"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/tags?post=2997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}