Desktopanwendungen erstellen: Winforms (C# & .Net)

Nachdem wir in den letzten Artikeln der Markdown Desktopanwendungsserie uns mit der Welt von Javascript und ihren Möglichkeiten beschäftigt haben, wird es nun spezieller. Wir schauen uns an, wie wir die Anwendung mithilfe von Winforms, C# und der .Net Plattform auf Windows umsetzen können. Dies ist schon ein drastischer Sprung, wie wir in den folgenden Artikeln sehen werden. Aber lass uns erst einmal mit dem warum beginnen?

Warum .Net?

Wenn man sich entscheiden möchte, welchen Tech-Stack man für seine Anwendung verwenden will, kommt man nicht um die Frage der Plattform herum. Bei Desktopanwendungen gibt es dabei drei unterschiedliche: Windows, Linux und MacOS. Letzteres ist gar nicht überraschend nur auf Apple Geräten verfügbar. Dabei ist es für mich schon sehr interessant, wie getrennt die drei Welten im Bereich der Anwendungsentwicklung auf den ersten Blick scheinen. Man stolpert schon öfters über Anwendungen, die nur z. B. auf Windows oder MacOS verfügbar sind.

Man hat nicht mehr auf der Betriebssystemebene die Vorteile, die wir noch aus dem Webbereich kannten. Dies wirkt ein wenig veraltet, da es mit modernen, interpretierten Sprachen wie Javascript (über NodeJS) oder Python gar kein Problem ist, die Software auf verschiedenen Betriebssystemen auszuführen. Auch gehört auf die Liste Java, da es eines der größten Vorteile der Sprache war (Write once, run everwhere). Doch diese Traumlandschaft endet meist, wenn man sich mit GUI’s beschäftigt. Dieser Bereich, ob auf dem PC oder auf dem Smartphone, ist immer noch mit einer harten Plattformtrennung verbunden. Doch welche Plattformen sind wie relevant heutzutage. Dafür müssen wir in die Statistiken schauen:

BetriebssystemAnteil
Windows75.54%
Mac14.98%
Linux2.45%
ChromeOS2,22 %
weitere/unbekannte4.81%
Werte aus dem Mai 2022

So ist Windows mit Abstand das beliebteste Betriebssystem. Das sollte uns erst einmal nicht stören, da wir in dieser Serie uns verschiedene Wege für die Entwicklung von Desktopanwendungen anschauen und in diesem Bereich ist Windows eine dominante Kraft.
Wenn es um das Programmieren für Windows geht, kommt man nicht um .Net Plattform herum. Diese ist der von Microsoft entwickelte und empfohlene Weg, Anwendungen auf Windows zu schreiben. Also schauen wir uns an, was sie zu bieten hat:

Winforms & WPF & UWP & App SDK & MAUI

Denn es gibt schon eine Auswahl an Wegen, seine GUI Anwendung zu schreiben.
Winforms ist die älteste GUI Bibliothek und stammt aus dem Jahr 2001. Jedoch ist sie durch ihre einfache Bedienung bis heute eine beliebte Möglichkeit, Desktopanwendungen für Windows zu bauen und auch unsere Wahl in diesem Fall.
WPF kam ein paar Jahre später (2006) und beinhaltet einen viel größeren Funktionsumfang, was aber auch mit einer steileren Lernkurve verbunden ist. Auch basiert die Architektur auf dem MVC Pattern.
UWP war dann die nächste Möglichkeit, die mit der Veröffentlichung von Windows 10 kam und den Gedanken der „Universal Windows Platform“ in sich trägt.
App SDK kann man mehr oder weniger als Nachfolger der UWP Plattform ansehen, da diese von Microsoft als „veraltet“ angesehen wird (sie konnte sich nicht durchsetzen). Deswegen versucht Microsoft mit dem App SDK die WIN32 (also das Format, mit dem alle Winforms, WPF und C++ Programme arbeiten) mit den Funktionen, die seit Windows 8 und später in der UWP Plattform eingeführt worden waren, zu erweitern.
MAUI bildet zugleich aber noch einmal eine ganz andere Variante. Diese Plattform ist für die Cross-Plattform Entwicklung zwischen Android, iOS, Windows und Linux geplant und soll Flutter Konkurrenz bieten.

Winforms

Also, lass uns nun endlich starten. Wichtig ist, dass ihr auf einem Windows System Visual Studio samt der „:NET-Desktopentwicklung“ Option ausgewählt habt. ![Screenshot 2022-06-11 210954.png](….\Desktop\Screenshot 2022-06-11 210954.png)Wenn das abgeschlossen ist, können wir ein neues Projekt erstellen. Dafür wählen wir eine Windows-Forms-App aus und geben ihr den Namen „MarkdownEditor“.

Nach der Erstellung sieht das Fenster so aus. Jetzt geht es an das UI:
Suchen wir nach dem Toolbox-Menü unter Ansicht->Toolbox.

Hier können wir alle Elemente sehen, die unsere Anwendung haben kann. Unsere Anwendung besteht aus 2 Feldern, wie schon zuvor. So nutzen wir einen SplitContainer dazu. Im Bereich des Panel 1 kommt ein RichTextBox hinzu, die unter „Dock“ die Option „Fill“ bekommt.


Starten wir unsere App, haben wir jetzt schon ein Textfeld, in das wir schreiben können.


Beim Webview wird es schon ein wenig komplizierter. Für dieses Tutorial greife ich auf den WebView2 zurück, der auf Chromium (über Edge) basiert. Auch nutzen wir für die Markdownerstellung „markdig“.

Beide müssen über NuGet installiert werden. Nachdem das passiert ist, sehen wir nun unter der Toolbox das Element WebView2. Dieses ziehen wir in Panel 2 rein und setzen wieder „Dock“ auf „Fill“.
Machen wir nun einen Doppelklick auf den Textbereich, so kommen wir in den Codebereich, wo die Events gehandhabt werden. Winforms arbeitet sehr fundamental mit Events. So wurde die „richTextBox1_TextChanged“ Funktion erstellt, die bei jeder Textänderung ausgeführt wird.
So bekommen wir den aktuellen Inhalt der RichTextBox über .Text und wandeln diese in Markdown um. Danach sagen wir dem WebView, dass er diesen String anzeigen soll.

var md = richTextBox1.Text;
var html = Markdig.Markdown.ToHtml(md);
webView21.CoreWebView2.NavigateToString(html); // Spoiler, wird leider nicht so leicht funktionieren

Jedoch bekommen wir eine Fehlermeldung, wenn wir unsere Anwendung ausführen und im Textbereich was schreiben wollen.

Um dies zu verhindern, müssen wir sicher stellen, dass der WebView gelanden und verfügbar ist. Einerseits aktivieren wir das asynchrone Laden des Webviews, andererseits schauen wir, ob der Webview initialisiert ist.

private bool WebViewIsLoaded = false;
public Form1()
{
    InitializeComponent();
    webView21.EnsureCoreWebView2Async();
}

private void richTextBox1_TextChanged(object sender, EventArgs e)
{
    var md = richTextBox1.Text;
    var html = Markdig.Markdown.ToHtml(md);
    if (WebViewIsLoaded)
    {
        webView21.CoreWebView2.NavigateToString(html);
    }
}

private void webView21_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
    WebViewIsLoaded = true;
}

Jetzt müsste unsere Anwendung funktionieren! Yeah 🎉

Laden und Speichern

Für laden und speichern von Dateien brauchen wir eine Menübar. Doch anstelle, dass wir auf komplexe Eventsysteme zurückgreifen müssen, können wir einfach weiter machen, wie zuvor. Wir nehmen aus der Toolbox das Element „MenuStrip“ und fügen dazu noch es hinzu und fügen die Unterpunkte hinzu.

Jedes bekommt ein eigenes Event. Starten wir mit dem Speichern Event:

Als erstes holen wir uns den Markdown Text. Dann konfigurieren wir ein SaveFileDialog mit den passenden Filteroptionen für Markdown Files und schauen, ob der Dialog erfolgreich war. Wenn ja, dann können wir mit den Streamwriter unter der herausgesuchten Adresse die Datei hinterlegen.

string md = richTextBox1.Text;

SaveFileDialog saveFileDialog1 = new SaveFileDialog
{
    Filter = "md files (*.md)|*.md",
    RestoreDirectory = true
};

if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
    StreamWriter file = new StreamWriter(saveFileDialog1.FileName.ToString());
    file.WriteLine(md);
    file.Close();
}

Für das Öffnen sieht es ähnlich aus. Wir konfigurieren den OpenFileDialog und wenn es wieder geklappt hat, lesen wir die Datei und schreiben den Inhalt in das Textfeld.

var fileContent = string.Empty;

OpenFileDialog openFileDialog1 = new OpenFileDialog
{
    Filter = "md files (*.md)|*.md",
    RestoreDirectory = true
};

if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
    var fileStream = openFileDialog1.OpenFile()
    using StreamReader reader = new StreamReader(fileStream);
    fileContent = reader.ReadToEnd();
}
richTextBox1.Text = fileContent;

Als letztes wollen wir die Datei noch speichern. Dass lösen wir einfach mit einem Application.Exit();. Nun haben wir alles wieder zusammen, wie schon bei Tauri.

Fazit

Immer noch bin ich ein bisschen überrascht. Winforms ist jetzt schon fast 20 Jahre alt, sollte durch einige Technologien abgelöst werden und schlägt sich heute immer noch relativ gut. Das liegt einerseits an der umfangreichen Integration innerhalb von Visual Studio, aber auch an ihrer einfachen Struktur innerhalb der Anwendung. Natürlich findet sie auch ihre Grenzen bei komplexeren Anwendungen, aber dafür sollten wir längst schon genügend Alternativen haben. Einfachheit mit dem WYSIWYG Editor und keine Pflicht. auf das MVC Pattern kann aber immer noch sehr gut sein. Natürlich muss man damit leben, dass die Anwendung diesen typischen „Windows Look“ aus den 2000er hat. Aber dafür mit einer fantastischen Dateigröße von 1 Mb (frameworkabhangig, x86; aber in Zeiten von Electron Anwendungen von 200Mb eine willkommene Abwechslung). Auch das Alter scheint für Microsoft kein Problem zu sein.

Es ist schon faszinierend, dass nach 13 Jahren Stillstand Winforms weiterentwickelt wird. Seit Jahren (oder auch Jahrzehnten) ist die Frage im Raum, ob WPF Winforms einmal ablösen wird. Später wurde sie durch die Frage erweitert, ob UWP Winforms und WPF ablösen soll, welche aber jetzt beantwortet worden war. Immer noch setzten nicht ganz unwichtige Unternehmen auf Winforms und die Community ist immer noch aktiv. So wird auch für Winforms noch teilweise eine Zukunft geben. Diese ist aber sehr abhängig davon, wann Microsoft eine Alternative schaffen kann, die viele Entwickler zum Wechsel veranlässt. Aber selbst dann würde es noch eine Menge an wichtigen Programmen geben, die mithilfe von Winforms verfasst worden waren. Diese müssten noch für eine lange Zeit weiter unterstützt werden.


Beitrag veröffentlicht

in

, ,

von

Schlagwörter:

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert