<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dotnet on</title><link>https://www.alexander-koepke.de/categories/dotnet/</link><description>Recent content in Dotnet on</description><generator>Hugo</generator><language>de-de</language><lastBuildDate>Sat, 31 May 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://www.alexander-koepke.de/categories/dotnet/index.xml" rel="self" type="application/rss+xml"/><item><title>Crow's NestMQTT</title><link>https://www.alexander-koepke.de/post/2025-06-01_crows_nestmqtt/</link><pubDate>Sat, 31 May 2025 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2025-06-01_crows_nestmqtt/</guid><description>&lt;h1 id="crows-nestmqtt-and-the-vibe-engineering-adventure"&gt;Crow&amp;rsquo;s NestMQTT and the Vibe Engineering Adventure&lt;/h1&gt;
&lt;p&gt;In the world of (Industrial) Internet of Things (IIoT), MQTT is a widely adopted messaging protocol. Whether you’re debugging a flaky device or trying to understand system-wide message flow, a good MQTT client is a lifesaver.&lt;/p&gt;
&lt;p&gt;There are many excellent MQTT clients available—like MqttExplorer, MQTTX, mqttui, and the classic &lt;code&gt;mosquitto_sub&lt;/code&gt;. However, none quite met &lt;strong&gt;my specific needs&lt;/strong&gt;. That kicked off a wild journey: building my own client, &lt;strong&gt;Crow&amp;rsquo;s NestMQTT&lt;/strong&gt;, while exploring how &lt;strong&gt;Generative AI can accelerate software development&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Running OPC UA server simulation in dotnet aspire</title><link>https://www.alexander-koepke.de/post/2025-05-07_opcplc_aspire/</link><pubDate>Wed, 07 May 2025 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2025-05-07_opcplc_aspire/</guid><description>&lt;h1 id="simulating-an-opc-ua-server-with-net-aspire-and-opc-plc"&gt;Simulating an OPC UA Server with .NET Aspire and OPC PLC&lt;/h1&gt;
&lt;p&gt;Deploying an OPC UA server simulation is a common need during development and testing of industrial IoT applications.
Recently, a customer asked how to set up such a simulation using &lt;strong&gt;.NET Aspire&lt;/strong&gt;, in order to streamline development
workflows and easily monitor system components, logs, metrics, and inter-service communication.&lt;/p&gt;
&lt;p&gt;.NET Aspire provides an ideal environment for orchestrating microservices and dependencies, making it a great fit for
hosting a simulated OPC UA server. For the server simulation, I use the free and open-source
&lt;a href="https://github.com/Azure-Samples/iot-edge-opc-plc"&gt;OPC PLC&lt;/a&gt; provided by Microsoft. While it&amp;rsquo;s possible to run the
server from source, I prefer using the containerized version published on the Microsoft Container Registry (MCR),
which integrates more easily into an Aspire-based solution.&lt;/p&gt;</description></item><item><title>Zeit-Trennzeichen bei DateTime</title><link>https://www.alexander-koepke.de/post/2016-07-14-zeit-trennzeichen-bei-datetime/</link><pubDate>Thu, 14 Jul 2016 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2016-07-14-zeit-trennzeichen-bei-datetime/</guid><description>&lt;p&gt;Diese Woche hat es das .NET geschafft mich zu überraschen, ein Programm ist beim Kunden mit italienischen Windows immer wieder abgestürzt. Nach langem Suchen hat ein Kollege das Problem erkannt, was durch das folgende Beispiel veranschaulicht wird:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd"&gt;var&lt;/span&gt; ci = &lt;span style="color:#ff79c6"&gt;new&lt;/span&gt; CultureInfo(&lt;span style="color:#f1fa8c"&gt;&amp;#34;it-IT&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd"&gt;var&lt;/span&gt; dateTime = DateTime.Now;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd"&gt;var&lt;/span&gt; str = dateTime.ToString(&lt;span style="color:#f1fa8c"&gt;&amp;#34;dd.mm.yyyy hh:mm:ss&amp;#34;&lt;/span&gt;, ci);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Console.WriteLine(str);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ausgabe (.NET 3.5): 14.07.2016 &lt;strong&gt;20.45.30&lt;/strong&gt;&lt;br&gt;
Ausgabe (.NET 4.0): 14.07.2016 &lt;strong&gt;20:45:30&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In der Ausgabe erkennt man, dass abhängig von der .NET Version, das Zeit-Trennzeichen ändert. Aber warum wird das Trennzeichen überhaupt verändert, es wurde doch eine feste Format-Zeichenkette angegeben? Die &lt;a href="https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx#escape"&gt;Dokumentation&lt;/a&gt; beschreibt:&lt;br&gt;
The &amp;ldquo;d&amp;rdquo;, &amp;ldquo;f&amp;rdquo;, &amp;ldquo;F&amp;rdquo;, &amp;ldquo;g&amp;rdquo;, &amp;ldquo;h&amp;rdquo;, &amp;ldquo;H&amp;rdquo;, &amp;ldquo;K&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;M&amp;rdquo;, &amp;ldquo;s&amp;rdquo;, &amp;ldquo;t&amp;rdquo;, &amp;ldquo;y&amp;rdquo;, &amp;ldquo;z&amp;rdquo;, &lt;strong&gt;&amp;quot;:&amp;quot;&lt;/strong&gt;, or &amp;ldquo;/&amp;rdquo; characters in a format string are interpreted as custom format specifiers rather than as literal characters. To prevent a character from being interpreted as a format specifier, you can precede it with a backslash (\), which is the escape character.&lt;/p&gt;</description></item><item><title>Performance Vortrag aus 2015</title><link>https://www.alexander-koepke.de/post/2016-06-13-performance-vortrag-aus-2015/</link><pubDate>Mon, 13 Jun 2016 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2016-06-13-performance-vortrag-aus-2015/</guid><description>&lt;p&gt;Letztes Jahr habe ich einen Vortrag zum Thema Performance gehalten, der Vermitteln sollte warum dieses Thema jeden (.NET-)Entwickler betrifft.&lt;/p&gt;
&lt;p&gt;Nachdem ich mir jetzt die Zeit genommen habe um auch die Sprechernotizen aka &amp;ldquo;Tonspur&amp;rdquo; auf zuschreiben, konnte ich den Vortrag online stellen:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/koepalex/performance_talk_2015"&gt;https://github.com/koepalex/performance_talk_2015&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vielleicht ist der Vortrag für jemanden Hilfreich :)&lt;/p&gt;</description></item><item><title>Debugging von Performance Problemen in .NET</title><link>https://www.alexander-koepke.de/post/2013-11-27-debugging-von-performance-problemen-in-net/</link><pubDate>Wed, 27 Nov 2013 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2013-11-27-debugging-von-performance-problemen-in-net/</guid><description>&lt;p&gt;Die Analyse von Speicherproblemen ist eine Aufgabe die bei großen .NET Anwendungen häufiger vorkommt. In C++ wurde gesucht, wer welche Speicherblöcke angefordert und nicht wieder freigegeben hat und im .NET Umfeld wird eben gesucht warum der Gabarge-Collector den Speicher nicht freigeben kann. Oder man sucht warum einige Benutzeraktionen besonders lange benötigen. Für die Analyse gibt es eine ganze Reihe guter kommerzieller Programme, auf diese möchte ich jedoch nicht eingehen, sondern ein paar kostenlosen Alternativen vorstellen.&lt;/p&gt;</description></item><item><title>Neues vom GC in .NET 4.0 und 4.5</title><link>https://www.alexander-koepke.de/post/2013-10-21-neues-vom-gc-in-net-4-0-und-4-5/</link><pubDate>Mon, 21 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2013-10-21-neues-vom-gc-in-net-4-0-und-4-5/</guid><description>&lt;p&gt;Heute möchte ich etwas über Erneuerungen im .NET 4.0 / 4.5 sprechen. Das genannte bezieht sich auf den Workstation Garbage-Collector. Die Informationen für den Server Garbage-Collector entnehmen sie bitte den Links. Beginnen wir jedoch zunächst mit einer kurzen Auffrischung.&lt;/p&gt;
&lt;h3 id="wiederholung"&gt;Wiederholung&lt;/h3&gt;
&lt;p&gt;Das .NET Framework unterteilt seinen Heap in verschiedene Generationen.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In der &lt;strong&gt;Gen0&lt;/strong&gt; werden fast alle Objekte erstellt. Die Anfangsgröße beträgt rund 256KB.&lt;/li&gt;
&lt;li&gt;In der &lt;strong&gt;Gen1&lt;/strong&gt; werden Objekte gespeichert die &lt;em&gt;eine&lt;/em&gt; Garbage-Collection überlebt haben. Die Anfangsgröße beträgt rund 2 MB.&lt;/li&gt;
&lt;li&gt;In der &lt;strong&gt;Gen2&lt;/strong&gt; werden Objekte gespeichert die &lt;em&gt;mehr als eine&lt;/em&gt; Garbage-Collection überlebt haben Die Anfangsgröße beträgt 10 MB.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Die soeben genannten Anfangsgrößen können zur Laufzeit variiert werden. Am stärksten wird sich i.A. die Größe der Gen2 verändern (wachsen), da die Gen2 als &lt;em&gt;Endlager&lt;/em&gt; für alle länger benötigten Objekte dient.&lt;/p&gt;</description></item><item><title>GetHashCode dein Freund und Sorgenkind</title><link>https://www.alexander-koepke.de/post/2013-10-20-gethashcode-dein-freund-und-sorgenkind/</link><pubDate>Sun, 20 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2013-10-20-gethashcode-dein-freund-und-sorgenkind/</guid><description>&lt;p&gt;Eine wichtige Methode beim Arbeiten im .NET Umfeld ist GetHashCode. Sie gibt einen 32 Bit Integer zurück der das Objekt identifizieren soll. Der Hash-Code beschreibt also die Identität des Objektes (im Gegensatz zur Speicherreferenz auf das Objekt).&lt;/p&gt;
&lt;p&gt;Daraus leitet sich die Frage ab &lt;em&gt;Wann zwei Objekte die selbe Identität besitzen?&lt;/em&gt; Im Falle einer Object-Relational-Mapper Klasse beispielsweise, wenn die Instanzen der O/R-Mapper Klasse auf ein und die selbe Zeile(n) der selben Tabelle(n) der selben Datenbank(en) verweisen. Klassischer weise durch eine Kette von Primary-Keys. Der Hash-Code ist auch ein Sorgenkind eines Entwicklers da schon hier die Probleme beginnen. Eine einfach Implementierungen könnte sein:&lt;/p&gt;</description></item><item><title>Pipe aus eigenen Programmen nutzen</title><link>https://www.alexander-koepke.de/post/2013-10-13-pipe-aus-eigenen-programmen-nutzen/</link><pubDate>Sun, 13 Oct 2013 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2013-10-13-pipe-aus-eigenen-programmen-nutzen/</guid><description>&lt;p&gt;Mittels der von Unix Systemen bekannten Pipe (&lt;em&gt;|&lt;/em&gt;) ist es auch unter Windows (via CMD-Line) möglich einzelne Kommandos zu verbinden. Die Pipe ermöglicht es die Ausgabe vom dem vorherigen Kommando direkt als Input des aktuellen Kommandos zu verwenden. Beispielsweise den Inhalt einer Datei einem Skript zu übergeben: &lt;code&gt;type input.md | perl Markdown.pl &amp;gt; output.html&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Logisch gesehen Ersetzt der Inhalt der Pipe ein einzelnes Konsolen-Argument. Um diese Funktionalität auch in den eigenen (Konsolen-) Programme verwenden zu können, sind im Allgemeinen nur zwei Erweiterungen notwendig.&lt;/p&gt;</description></item><item><title>Ermitteln des PID (Processidentifier) des Vaterprozesses</title><link>https://www.alexander-koepke.de/post/2012-10-14-ermitteln-des-pid-processidentifier-des-vaterprozesses/</link><pubDate>Sun, 14 Oct 2012 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2012-10-14-ermitteln-des-pid-processidentifier-des-vaterprozesses/</guid><description>&lt;p&gt;In manchen Fällen ist es notwendig heraus zu finden, welches der Vaterprozess eines Prozesses ist. Dafür gibt es im Allgemeinen drei verschiedene Lösungen im Windows .NET Umfeld.&lt;/p&gt;
&lt;p&gt;Die häufigste Lösung ist die Verwendung von &lt;strong&gt;Performancecountern&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd"&gt;var&lt;/span&gt; process = FindProcess(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;using&lt;/span&gt; (&lt;span style="color:#8be9fd"&gt;var&lt;/span&gt; pC = &lt;span style="color:#ff79c6"&gt;new&lt;/span&gt; PerformanceCounter(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#34;Process&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#34;Creating Process ID&amp;#34;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#f1fa8c"&gt;&amp;#34;{0}#{1}&amp;#34;&lt;/span&gt;, process.ProcessName, &lt;span style="color:#bd93f9"&gt;1&lt;/span&gt;),   
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; process.MachineName)) 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd"&gt;int&lt;/span&gt; pid = (&lt;span style="color:#8be9fd"&gt;int&lt;/span&gt;)pC.NextValue(); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Console.WriteLine(&lt;span style="color:#f1fa8c"&gt;&amp;#34;parent pid = {0}&amp;#34;&lt;/span&gt;, pid); 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Die Verwendung von Performancecountern im Allgemeinen kann zwei mögliche Nachteile haben:&lt;/p&gt;</description></item><item><title>DSLs, Extension Methods und Fluent Interfaces</title><link>https://www.alexander-koepke.de/post/2012-07-28-dsls-extension-methods-und-fluent-interfaces/</link><pubDate>Sat, 28 Jul 2012 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2012-07-28-dsls-extension-methods-und-fluent-interfaces/</guid><description>&lt;p&gt;In den letzten Jahren wurde in der Softwareentwicklung viel über Domänenspezifische Sprachen (domain specific language, kurz: DSLs) geschrieben. DSLs sollen von einem Domänenexperten gelesen werden können, auch ohne das die Domänenexperten über Programmierkenntnisse verfügen. DSLs können auch Entwicklern helfen die Quelltexte leserlicher zu machen, sowie Fehler zu vermeiden. Die Quelltextzeile:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;if (!SessionEstablished)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ist einfach verständlich (für diejenigen welche eine C ähnliche Syntax verstehen), als Alternative könnte folgende Quelltextzeile dienen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;if (Not(SessionEstablished))&lt;/p&gt;</description></item><item><title>Inversion Of Control(-Container), Service Locator und Dependency Injection</title><link>https://www.alexander-koepke.de/post/2012-06-08-inversion-of-control-container-service-locator-und-dependency-injection/</link><pubDate>Fri, 08 Jun 2012 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2012-06-08-inversion-of-control-container-service-locator-und-dependency-injection/</guid><description>&lt;p&gt;IOC-Container und DI sind zurzeit in vielen Fachzeitschriften diskutiert. Hier der Versuch einer kompakte Übersicht, die IOC, DI, SL und IOC-Container im Zusammenspiel erklärt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Inversion Of Control&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Beschreibt ein Paradigma zum Entwerfen von Frameworks. Ein Unterschied zwischen einem Framework und einer Bibliothek besteht darin, dass in einem Framework Methoden vom Verwender des Framework aufgerufen werden. Dies verändert den Kontrollfluss, bei einer klassischen Bibliothek, ruft der Verwender eine Methode auf, deren Funktionalität wird abgearbeitet und die Methode kehrt zum Aufrufer zurück. Die Steuerung des Kontrollflusses liegt also in der Hand des Verwenders der Bibliothek. Ein gutes Beispiel ist das .NET Framework, der Verwender kann Methoden über Events an Ereignisse binden, dass .NET Framework entscheidet, wann es die Funktionalität des Verwenders aufruft.&lt;/p&gt;</description></item><item><title>Vermeidung von switch-case zur Typen Bestimmung beim Aufruf von generischen Methoden</title><link>https://www.alexander-koepke.de/post/2012-04-20-vermeidung-von-switch-case-zur-typen-bestimmung-beim-aufruf-von-generischen-methoden-3/</link><pubDate>Fri, 20 Apr 2012 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2012-04-20-vermeidung-von-switch-case-zur-typen-bestimmung-beim-aufruf-von-generischen-methoden-3/</guid><description>&lt;p&gt;In der Entwicklung mit .NET hat man öfter folgendes Problem:&lt;/p&gt;
&lt;p&gt;Methoden sind generisch implementiert und zu verwendende Objekte sind nur in Form von Referenzen auf Basistypen vorhanden (z.B. System.Array, System.Object). Diese Referenzen können nicht direkt an generische Methode übergeben werden (ergibt einen Compile Fehler).&lt;/p&gt;
&lt;p&gt;Häufig liegen daher Typinformationen als String vor (über FullName-Property, aus Konfigurationsdatei, …). Diese Informationen werden anschließend verwendet, um den Typ der Referenz über switch-case aufzulösen.&lt;/p&gt;
&lt;p&gt;Zum Beispiel:&lt;/p&gt;</description></item><item><title>UnauthorizedAccessException beim Kopieren einer Datei</title><link>https://www.alexander-koepke.de/post/2011-11-07-unauthorizedaccessexception-beim-kopieren-einer-datei/</link><pubDate>Mon, 07 Nov 2011 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2011-11-07-unauthorizedaccessexception-beim-kopieren-einer-datei/</guid><description>&lt;p&gt;Kopieren, verschieben, umbenennen und löschen von Dateien gehören zu häufigen Aufgaben eines Softwareentwicklers. In diesem Beitrag sollen ein paar Dinge aufgezeigt werden die einem beim kopieren von Datein vielleicht nicht bewusst sind. Wie kopiert man jetzt am besten eine Datei? Eine Variante ist die statische Methode der Klasse File:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;File.Copy(“C:\\input\\test.bmp“, “C:\\output\\test.bmp“, &lt;span style="color:#ff79c6"&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Damit man sich Überprüfungen wie ob die Datei bereits existiert (File.Exist()) sparen kann, wird die Überladung der Copy-Methode verwendet, welche bestehende Dateien überschreibt. Solange man die Software nur mit administrativen Rechten betreibt, hat man alles richtig gemacht. Muss die Software auch mit Benutzer Rechten arbeiten, kann man hier eine UnauthorizedAccessException bekommen. Dies würde zum Beispiel eintreten wenn eine schreibgeschützte Datei, bereits im Zielverzeichnis existiert und erneut in dieses Verzeichnis kopiert werden soll. Die .Net Implementierung der Copy-Methode fordert Berechtigungen on demand an, das bedeutet erst, wenn besondere Zugriffsrechte benötigt werden, werden diese angefordert. Als Benutzer hat man aber nicht die benötigten Rechte um schreibgeschützte Dateien zu überschreiben. Um diesen speziellen Fall zu lösen, könnte man nach dem kopieren die Attribute der Datei verändern (dafür genügen die Benutzer Rechte):&lt;/p&gt;</description></item><item><title>WPF RichTextBox mit Durchgestrichenden Text</title><link>https://www.alexander-koepke.de/post/2011-06-18-wpf-richtextbox-mit-durchgestrichenden-text/</link><pubDate>Sat, 18 Jun 2011 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2011-06-18-wpf-richtextbox-mit-durchgestrichenden-text/</guid><description>&lt;p&gt;Um bei einer WPF RichTextBox einen Text &lt;strong&gt;Fett&lt;/strong&gt;, &lt;em&gt;Kursiv&lt;/em&gt; oder Unterstrichen darzustellen ist nicht viel notwenig. Eigentlich muss man im XAML nur einen (Toggle)Button definieren, der ein Kommando (EditingCommands) an die RichTextBox sendet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;&amp;lt;ToggleButton&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;Command=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;EditingCommands.ToggleItalic&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;CommandTarget=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;{Binding ElementName=myRichTextBox}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;Content=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;Italic&amp;#34;&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;&amp;lt;RichTextBox/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Genauso einfach verhält es sich einen Text Hochgestellt oder Tiefgestellt darzustellen, mann muss nur zusätzlich noch die Schrift-Familie des Hinter der RichTextBox liegenden Dokumentes verändern:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;&amp;lt;ToggleButton&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;Command=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;EditingCommands.ToggleSubscript&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;CommandTarget=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;{Binding ElementName=myRichTextBox}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#50fa7b"&gt;Content=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;Subscript&amp;#34;&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;&amp;lt;RichTextBox/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#6272a4"&gt;&amp;lt;!--on default fontfamily subscript and superscript dont work!!--&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;&amp;lt;FlowDocument&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;FontFamily=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;Palatino Linotype&amp;#34;&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;FontSize=&lt;/span&gt;&lt;span style="color:#f1fa8c"&gt;&amp;#34;14&amp;#34;&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff79c6"&gt;&amp;lt;/RichTextBox&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Die Veränderungen an dem Text funktionieren in zwei Modi:&lt;/p&gt;</description></item><item><title>Events über Threadgrenzen</title><link>https://www.alexander-koepke.de/post/2011-06-10-events-uber-threadgrenzen/</link><pubDate>Fri, 10 Jun 2011 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2011-06-10-events-uber-threadgrenzen/</guid><description>&lt;p&gt;Die meisten Tools/Programme verrichten Ihre Arbeit in Threads um die Oberfläche (UI) nicht zu blockieren. Eine &amp;ldquo;Kommunikations-Möglichkeit&amp;rdquo; um die UI beim Eintreten von bestimmten Gegebenheiten zu benachrichtigen sind Events. Ein Event im .Net ruft seine Ziele (InvokationList) aus dem Thread auf, aus dem es &amp;ldquo;gefeuert&amp;rdquo; wird. UI Controls, können i.A. nur im Mainthread arbeiten. Einen Zugriff aus einen anderen Thread führt zu einer Exception. Über das Interface ISynchronizedInvoke (implementiert von allen .Net UI Controls):&lt;/p&gt;</description></item><item><title>Tracing/Logging und die Config-Datei</title><link>https://www.alexander-koepke.de/post/2011-06-08-tracinglogging-config-file/</link><pubDate>Wed, 08 Jun 2011 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2011-06-08-tracinglogging-config-file/</guid><description>&lt;p&gt;Logging von Informationen ist so gut wie in jedem Programm notwendig. Nicht alle Entwickler können oder wollen ein professionelles Log-Tool wie z.B. &lt;a href="http://logging.apache.org/log4net/index.html"&gt;log4net&lt;/a&gt; oder &lt;a href="http://nlog-project.org/"&gt;nlog&lt;/a&gt; verwenden. In vielen Fällen reichen auch Debug.WriteLine oder Trace.WriteLine (letztes schreibt auch wenn die Software im Modus „Release“ kompiliert wurde).&lt;/p&gt;
&lt;p&gt;Über eine Config-Datei lassen sich u.a. verschiedene TraceListener auswählen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ConsoleTraceListener&lt;/li&gt;
&lt;li&gt;DefaultTraceListener&lt;/li&gt;
&lt;li&gt;DelimitedListTraceListener&lt;/li&gt;
&lt;li&gt;EventLogTraceListener&lt;/li&gt;
&lt;li&gt;EventSchemaTraceListener&lt;/li&gt;
&lt;li&gt;TextWriterTraceListener&lt;/li&gt;
&lt;li&gt;XmlWriterTraceListener&lt;/li&gt;
&lt;li&gt;eigene Implementierungen welche sich von TraceListener ableiten&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Damit kann man ohne neu kompilieren des Assemblies einfach den Ausgabeort des Trace-Informationen verändern.&lt;/p&gt;</description></item><item><title>Einiges über IDisposable</title><link>https://www.alexander-koepke.de/post/2011-06-07-something-idisposable/</link><pubDate>Tue, 07 Jun 2011 00:00:00 +0000</pubDate><guid>https://www.alexander-koepke.de/post/2011-06-07-something-idisposable/</guid><description>&lt;p&gt;Das Standard Interface IDisposable welches  zur &amp;ldquo;Freigabe&amp;rdquo; von Ressourcen in .Net dient ist recht Einfach:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;public&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;interface&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;IDisposable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#ff79c6"&gt;void&lt;/span&gt; Dispose();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nur dieses Interface zu Implementieren reicht in vielen Fällen nicht aus. Es gibt z.B. einen FxCop Fehler &lt;a href="http://msdn.microsoft.com/en-us/library/ms244737(v=vs.80).aspx"&gt;Implement IDisposable correctly&lt;/a&gt;, dieser erscheint u.a. bei non-sealed Klassen welche keinen Medthode mit der Signatur protected virtual Dispose(bool) besitzen.  IDisposable zu Implementieren wird nötig wenn man:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;unmanged (native) Ressourcen lädt um diese wieder freizugeben&lt;/li&gt;
&lt;li&gt;managed Felder besitzt, welche wiederum IDisposable implementieren&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Im folgenden Beispiel zeigt eine (nach FxCop komplette Implementierung) einer Basis-Klasse  und einer Kind-Klasse:&lt;/p&gt;</description></item></channel></rss>