<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C and it&#039;s sharp &#187; Bernd</title>
	<atom:link href="http://berndhengelein.de/author/bernd/feed/" rel="self" type="application/rss+xml" />
	<link>http://berndhengelein.de</link>
	<description>berndhengelein.de</description>
	<lastBuildDate>Sat, 30 Oct 2010 20:08:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Compiler warning CS0067 – es muss nicht immer #pragma sein</title>
		<link>http://berndhengelein.de/2010/07/compiler-warning-cs0067-es-muss-nicht-immer-pragma-sein/</link>
		<comments>http://berndhengelein.de/2010/07/compiler-warning-cs0067-es-muss-nicht-immer-pragma-sein/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 23:15:10 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Clean Code]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=331</guid>
		<description><![CDATA[Da ist es wieder. Der Compiler spuckt die Warnung CS0067 “The event ‘XXX’ is never used” aus. Das kann z.B. passieren, wenn das Interface ICommand implementiert wird, das Command aber immer ausführbar sein soll. Das Event CanExecuteChanged muss also nie gefeuert werden:
&#160;
&#160;

public class SomeCommand : ICommand
{
	public void Execute(object parameter)
    {
		// do sth.
	}

	public [...]]]></description>
			<content:encoded><![CDATA[<p><img title="warningSign" style="border-right: 0px; border-top: 0px; display: inline; margin: 0px 15px 0px 0px; border-left: 0px; border-bottom: 0px" height="120" alt="warningSign" src="http://berndhengelein.de/wp-content/uploads/2010/07/warningSign1.png" width="120" align="left" border="0" />Da ist es wieder. Der Compiler spuckt die Warnung CS0067 “The event ‘XXX’ is never used” aus. Das kann z.B. passieren, wenn das Interface <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx" target="_blank">ICommand</a> implementiert wird, das Command aber immer ausführbar sein soll. Das Event <a href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.canexecutechanged.aspx" target="_blank">CanExecuteChanged</a> muss also nie gefeuert werden:</p>
<p>&#160;</p>
<p>&#160;</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8b02cd47-cb25-475c-a736-c1566396800d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">public class SomeCommand : ICommand
{
	public void Execute(object parameter)
    {
		// do sth.
	}

	public bool CanExecute(object parameter)
    {
		return true;
	}

	public event EventHandler CanExecuteChanged;
}</pre>
</div>
<p>Bei obiger Imlementierung bekommt man beim Übersetzten die Compiler Warnung CS0067:</p>
<blockquote>
<p>warning CS0067: The event &#8216;CommandDemo.SomeCommand.CanExecuteChanged&#8217; is never used</p>
</blockquote>
<p>Was einem als erstes (zumindest mir) einfällt die Warning zu “beheben”, ist sie mit einem <a href="http://msdn.microsoft.com/en-us/library/x74w198a.aspx" target="_blank">#pragma Statement</a> kurzzeitig aus- und wieder einzuschalten:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f04c9229-dfdb-4384-9a1a-b71df3ac080f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">#pragma warning disable 0067
	public event EventHandler CanExecuteChanged;
#pragma warning restore 0067</pre>
</div>
<p>So richtig gut gefällt diese Lösung aber nicht. Bei Implementierungen, wo das Event später vielleicht doch einmal gefeuert wird, ist die Wahrscheinlichkeit ziemlich hoch, dass diese #pragma Statements vergessen werden und im Code verbleiben. Das ist nicht schön. Aber es gibt eine andere, (mittlerweile meiner Ansicht nach bessere) Lösung:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5970b024-3c25-4b4c-86ed-03a01738c95c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">public event EventHandler CanExecuteChanged { add{} remove{} }</pre>
</div>
<p>Durch das Hinzufügen der leeren Eventaccessors “add” und “remove” mache ich klar, dass dieser Event nicht verwendet wird. Da das Event sowieso nie gefeuert wird, ändert sich auch für den potentiellen Konsumenten des Events nichts. Wenn in einer späteren Phase dieser Event doch einmal ausgelöst werden soll, wird der Entwickler sofort mit einem Kompilerfehler darauf hingewiesen, das dies nicht möglich ist. Die leeren “add” und “remove” Accessoren müssen also entweder wieder entfernt oder entsprechend vollständig implementiert werden ==&gt; der Code bleibt sauber.</p>
<p>Wie man sieht, muss man also nicht sofort zum #pragma greifen, wenn man mit der Warnung CS0067 konfrontiert wird. Das Hinzufügen der leeren Eventaccessoren bietet eine elegante und saubere Lösung mit dem Fall umzugehen.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2010/07/compiler-warning-cs0067-es-muss-nicht-immer-pragma-sein/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>NUnit mit .NET 4.0 Assemblies verwenden</title>
		<link>http://berndhengelein.de/2010/07/nunit-mit-net-4-0-assemblies-verwenden/</link>
		<comments>http://berndhengelein.de/2010/07/nunit-mit-net-4-0-assemblies-verwenden/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 18:41:33 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[.NET 4.0]]></category>
		<category><![CDATA[Tipps]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=321</guid>
		<description><![CDATA[ Bei unseren Projekten stellen wir gerade von Visual Studio 2008 auf Visual Studio 2010 mit .NET 4.0 um. Der Umstieg läuft recht problemlos. Die Unittests sind alle mit dem NUnit Unittest Framework entwickelt. Ein kurzer Blick auf die NUnit Homepage zeigt, dass die aktuelle Version 2.5.5 mit .NET 4.0 funktioniert. Also, Version runtergeladen, entpackt [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://berndhengelein.de/wp-content/uploads/2010/07/lightbulb1.png"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 5px; display: inline; border-top: 0px; border-right: 0px" title="lightbulb" border="0" alt="lightbulb" align="left" src="http://berndhengelein.de/wp-content/uploads/2010/07/lightbulb_thumb1.png" width="119" height="119" /></a> Bei unseren Projekten stellen wir gerade von Visual Studio 2008 auf Visual Studio 2010 mit .NET 4.0 um. Der Umstieg läuft recht problemlos. Die Unittests sind alle mit dem NUnit Unittest Framework entwickelt. Ein kurzer Blick auf die <a href="http://nunit.org/" target="_blank">NUnit Homepage</a> zeigt, dass die aktuelle <a href="http://nunit.org/index.php?p=docHome&amp;r=2.5.5" target="_blank">Version 2.5.5</a> mit .NET 4.0 funktioniert. Also, Version runtergeladen, entpackt und alles kompiliert noch. Als Entwickler verwende ich den Unittestrunner von <a href="http://www.jetbrains.com/resharper/" target="_blank">Resharper</a>. Und siehe da, alle Tests laufen noch und sind grün. Perfekt!</p>
<p>Auf dem Buildrechner sieht es leider nicht so gut aus. Die Unittests laufen überhaupt nicht mehr. Dort werden die Tests mit dem Consolerunner von NUnit ausgeführt. Ein Aufruf desselben auf meinem Rechner bringt folgende (bzw. eine ähnliche) Ausgabe:</p>
<blockquote><p>Execution Runtime: net-2.0      <br />Unhandled Exception:       <br />System.BadImageFormatException: Could not load file or assembly &#8216;C:\Users\Bernd\documents\visual studio 2010\Projects\SomeProjects\SomeProject.Unittests\bin\Debug\SomeProject.Unittests.dll&#8217; or one of       <br />its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.       <br />File name: &#8216;C:\Users\Bernd\documents\visual studio 2010\Projects\SomeProjects\SomeProject.Unittests\bin\Debug\SomeProject.Unittests.dll&#8217;</p>
</blockquote>
<p>Was ist da los?</p>
<p>Die NUnit Assemblies selbst sind mit .NET 2.0 kompiliert. Der Consolerunner von NUnit läuft also auch mit der CLR 2.0 und kann somit keine Assemblies laden, die mit .NET 4.0 erstellt wurden. Glücklicherweise haben die Entwickler von NUnit genau für diese Fälle einen Kommandozeilenparameter für nunit-console.exe eingebaut. Mit dem Schalter <strong>“/framework” </strong>kann man angeben mit welcher .NET Runtime die Test ausgeführt werden sollen. Der korrekte Aufruf lautet also:</p>
<blockquote><p>nunit-console.exe /framework:v4.0.30319 bin\Debug\SomeProject.Unittests.dll</p>
</blockquote>
<p>Jetzt tritt keine Exception mehr auf und die Tests laufen auch auf der Console sauber durch.</p>
<p>Der Schalter war übrigens vor dem Umstieg (es wurde .NET 3.5 SP1 verwendet) nicht notwendig, da .NET 3.5 dieselbe CLR wie .NET 2.0 verwendet.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2010/07/nunit-mit-net-4-0-assemblies-verwenden/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TDD &#8211; ein Garant f&#252;r hei&#223;e Diskussionen</title>
		<link>http://berndhengelein.de/2010/03/tdd-ein-garant-fr-heie-diskussionen/</link>
		<comments>http://berndhengelein.de/2010/03/tdd-ein-garant-fr-heie-diskussionen/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 19:12:26 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=317</guid>
		<description><![CDATA[ 
Beim allmonatlichen Treffen der .NET User Group Franken hatten wir am 25.03.2010 einen interaktiven Vortrag zum Thema Test Driven Development (TDD). Interaktiv deshalb, weil die Vortragenden Jürgen Laude und Jan Welker an einem praktischen Beispiel mit Live Coding gezeigt haben, wie TDD funktioniert. Dabei handelte es sich nicht um ein konstruiertes Beispiel, sondern um [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 20px 15px 0px; display: inline; border-top: 0px; border-right: 0px" title="tdd" border="0" alt="tdd" align="left" src="http://berndhengelein.de/wp-content/uploads/2010/03/tdd.png" width="100" height="100" /> </p>
<p>Beim allmonatlichen Treffen der <a href="http://dodned.de" target="_blank">.NET User Group Franken</a> hatten wir am <a href="http://dodned.spaces.live.com/blog/cns!D8CA0F8474203D92!449.entry" target="_blank">25.03.2010</a> einen interaktiven Vortrag zum Thema <a href="http://de.wikipedia.org/wiki/Test-Driven_development" target="_blank">Test Driven Development (TDD)</a>. Interaktiv deshalb, weil die Vortragenden Jürgen Laude und Jan Welker an einem praktischen Beispiel mit Live Coding gezeigt haben, wie TDD funktioniert. Dabei handelte es sich nicht um ein konstruiertes Beispiel, sondern um ein Problem, welches Jan vor ein paar Jahren schon einmal in einem Projekt gelöst hatte. Es wurde ein spezieller Parser für RSS Feeds entwickelt, die nicht standardkonform aufgebaut sind.</p>
<p>Schon die Anzahl der Gäste an diesem Abend (mit knapp 40 Teilnehmern war der Raum prall gefüllt) hat gezeigt, dass das Thema Testen und testgetriebene Entwicklung viele Softwareentwickler umtreibt. Dementsprechend zahlreich und kontrovers waren auch die Fragen und Diskussionen an dem Abend. Ich möchte hier zu ein paar der diskutierten Punkten meinen Kommentar abgeben.</p>
<p><strong>TDD dient nicht dazu Fehler zu finden</strong></p>
<p>Ein Punkt, der auch von den Referenten angesprochen wurde ist, dass mit TDD nicht in erster Linie Fehler gefunden, sondern verhindert werden sollen. Dadurch, dass die Tests vor dem zu testenden Produktionscode geschrieben werden, ist man gezwungen, testbaren, modularen und lose gekoppelten Code zu schreiben. TDD ist also das Werkzeug des Entwicklers für gutes Design. Hat man sich dieses Sicherheitsnetz aus Unit Tests geschaffen, kann man viel furchtloser mit dem Code arbeiten. Während der ständigen Refaktorierungen, die bei TDD üblich sind, wird man sofort auf Fehler hingewiesen, die man eventuell eingebaut hat. Auch wird sichergestellt, dass sich beim Implementieren neuer Features keine Fehler in die bereits bestehende Funktionalität eingeschlichen haben.</p>
<p><strong>Sollten Internas einer Klasse getestet werden?</strong></p>
<p>Meine Vermutung ist, dass diese Frage hauptsächlich von Leuten aufgeworfen wird, die den Code nicht testgetrieben entwickelt haben. Wenn Unittests im Nachhinein geschrieben werden, schleichen sich Zweifel ein, ob auch wirklich alles getestet ist und ob nicht doch was vergessen wurde. Lieber eine Methode zuviel als zuwenig getestet. Bei testgetriebener Entwicklung wird gegen das öffentliche Interface getestet. Die privaten Methoden entwickeln sich während der Refaktorierungschritte. Es wird damit zu jedem Zeitpunkt sichergestellt, dass die privaten Methoden implizit über das öffentliche Interface mitgetestet werden. Wenn man den Drang verspürt eine private Methode testen zu wollen, ist das ein Code Smell der auf eine Umstrukturierung der Klasse hindeutet.</p>
<p><strong>Unittests können Integrations-, Akzeptanz- oder Systemtests nicht ersetzen</strong></p>
<p>Wenn im Zuge von TDD erstellte Unittests keine Fehler finden, müssen diese Fehler natürlich durch andere Tests gefunden werden. Hier können Integrationstests (die durchaus auch mit einem Unittest Framework geschrieben werden können) und natürlich auch Systemtests helfen. Wenn die Projektstruktur es zulässt, können auch Akzeptanztests (z.B. mit <a href="http://fitnesse.org/" target="_blank">FitNesse</a>) erstellt werden, die es leichter machen direkt mit dem Kunden zu kommunizieren. Bei Akzeptanztests werden die Tests in einer Sprache beschrieben, die sowohl der Entwickler als auch der Kunde versteht.</p>
<p>Natürlich gibt es auch andere Meinungen zu dem Thema. <a href="http://weblog.drescher-hackel.de/default.aspx" target="_blank">René Drescher-Hackel</a> hat z.B. auf seinem Blog den Post <a href="http://weblog.drescher-hackel.de/0E0DBC1B-56D6-400E-95BB-C631BE5BDEDE/Gedanken+zum+Test+Driven+Development+(TDD).content.aspx" target="_blank">Gedanken zum Test Driven Development (TDD)</a> veröffentlicht.</p>
<p>Es leuchtet ein, dass ein zweistündiges Event zum Thema TDD nicht alle Fragen beantworten und alle Zweifel ausräumen kann. Vielmehr ist es ein Denkanstoß und vielleicht ein Motivationsschub um die Ärmel hochzukrämpeln und TDD in eigenen Projekten anzuwenden und auszuprobieren.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2010/03/tdd-ein-garant-fr-heie-diskussionen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fehler bei der Installation des Visual Studio 2010 RC</title>
		<link>http://berndhengelein.de/2010/02/fehler-bei-der-installation-des-visual-studio-2010-rc/</link>
		<comments>http://berndhengelein.de/2010/02/fehler-bei-der-installation-des-visual-studio-2010-rc/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 12:22:44 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[VS 2010]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=312</guid>
		<description><![CDATA[Ich hatte das Problem, dass sich der Release Candidate von Visual Studio 2010 auf dem Windows XP Firmenrechner nicht installieren ließ. Das Setup brach mit der Fehlermeldung
&#8220;A problem has been encountered while loading the setup components. Canceling setup&#8221;
ab.
Eine Suche nach obigem Fehlertext hat keine Antwort zu Tage gefördert. Da ist es gut zu wissen, dass [...]]]></description>
			<content:encoded><![CDATA[<p>Ich hatte das Problem, dass sich der Release Candidate von Visual Studio 2010 auf dem Windows XP Firmenrechner nicht installieren ließ. Das Setup brach mit der Fehlermeldung</p>
<p><strong>&#8220;A problem has been encountered while loading the setup components. Canceling setup&#8221;</strong></p>
<p>ab.</p>
<p>Eine Suche nach obigem Fehlertext hat keine Antwort zu Tage gefördert. Da ist es gut zu wissen, dass im %TEMP% Verzeichnis während des Setups diverse Log Dateien angelegt werden.</p>
<p>In dem File &#8220;<strong>dd_error_vs_vstscore_100.txt</strong>&#8221; fand sich folgender Eintrag:</p>
<blockquote><p>[02/15/10,10:17:33] vs70uimgr: [2] UI Thread exiting with error code: -2147172341.<br />
[02/15/10,10:17:33] setup.exe: [0] StartUIManager(), RunScenario failure<br />
[02/15/10,10:17:33] setup.exe: [2] CSetupManager::RunIntro() &#8211; Failed to Start the UI Manager<br />
[02/15/10,10:17:36] setup.exe: [2] CSetupManager::RunLoadSetup() &#8211; Failed to Run the Intro</p></blockquote>
<p>Mit dieser Zusatzinformation hat mich die Suchmaschine meiner Wahl dann auch zu einem MSDN Forum Artikel geführt, welcher die Lösung parat hat: <a href="http://social.msdn.microsoft.com/Forums/en-US/setupprerelease/thread/dbcdcd52-d162-4460-9920-33c9ab54b36f">http://social.msdn.microsoft.com/Forums/en-US/setupprerelease/thread/dbcdcd52-d162-4460-9920-33c9ab54b36f</a></p>
<p>Der Lösung bestand darin, über den &#8220;Settings&#8221; Dialog in der Language Bar die Unterstützung für Schrifterkennung zu entfernen. Dannach lief das Setup ohne Probleme durch.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2010/02/fehler-bei-der-installation-des-visual-studio-2010-rc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WPF 4.0 &#8211; Verbesserungen beim Textrendering</title>
		<link>http://berndhengelein.de/2009/11/wpf-4-0-verbesserungen-beim-textrendering/</link>
		<comments>http://berndhengelein.de/2009/11/wpf-4-0-verbesserungen-beim-textrendering/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 22:15:58 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[.NET 4.0]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=302</guid>
		<description><![CDATA[Am 22. März 2010 wird Visual Studio 2010 als finales Produkt verfügbar sein. Damit ist auch eine neue Version des .NET Frameworks verbunden, .NET 4.0. Auch für WPF Entwickler wird so einiges Neues in .NET 4.0 enthalten sein. Lester Lobo stellt auf seinem Blog in der Reihe “New WPF 4 Features” die wichtigsten Neuerungen vor.
Natürlich [...]]]></description>
			<content:encoded><![CDATA[<p>Am 22. März 2010 wird <a href="http://www.microsoft.com/presspass/press/2009/oct09/10-19VSFinalStretchPR.mspx" target="_blank">Visual Studio 2010 als finales Produkt</a> verfügbar sein. Damit ist auch eine neue Version des .NET Frameworks verbunden, .NET 4.0. Auch für WPF Entwickler wird so einiges Neues in .NET 4.0 enthalten sein. <a href="http://blogs.msdn.com/llobo/default.aspx" target="_blank">Lester Lobo</a> stellt auf seinem Blog in der Reihe “<a href="http://blogs.msdn.com/llobo/archive/tags/New+WPF+4+features/default.aspx" target="_blank">New WPF 4 Features</a>” die wichtigsten Neuerungen vor.</p>
<p>Natürlich will ich nicht alles von Lester wiederkauen, aber eine Neuerung möchte ich doch herausstellen. Bei bisherigen WPF Anwendungen ist die Darstellung von Text mit kleiner Schrift teilweise etwas (manche sagen sogar sehr) unscharf. Der Artikel <a href="http://windowsclient.net/wpf/white-papers/wpftextclarity.aspx" target="_blank">Textclarity in WPF</a> auf <a href="http://windowsclient.net/" target="_blank">windowsclient.net</a> geht ziemlich gut auf diese Problematik und mögliche Workarounds ein. In .NET 4.0 ist es nun möglich das Textrendering mit zwei attached properties zu beeinflussen. </p>
<p>TextOptions.TextFormattingMode kann mit zwei unterschiedlichen Werten belegt werden. Einmal mit <em>Ideal</em>, was dem bisherigen WPF Textrendering entspricht oder mit <em>Display</em>, was die Darstellung bei kleinen Schriftarten schärfer aussehen lässt.</p>
<p>TextOptions.TextRenderingMode legt den Algorithmus für das Antialiasing fest und kann die Werte <em>Auto, Aliased, Greyscale</em> oder <em>ClearType</em> haben.</p>
<p>Der folgende Screenshot zeigt einige der Einstellungen für kleine und große Schrift:</p>
<p> <img src="http://berndhengelein.de/wp-content/uploads/2009/11/WPF4TextImprovements.png" alt="WPF4TextImprovements" title="WPF4TextImprovements" width="590" height="839" class="size-full wp-image-307" />
<p>Bei der kleinen Schrift sieht man eine deutliche Verbesserung der Lesbarkeit des angezeigten Textes. Das unscharfe, verwaschene Schriftbild ist einer klaren Darstellung gewichen, was vorallem bei Businessanwendungen mit WPF sehr wichtig ist. Wer jetzt schon die neuen Features von .NET 4.0 ausprobieren möchte, kann sich weiterhin die Beta 2 von Visual Studio 2010 <a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx">hier</a> herunterladen.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/11/wpf-4-0-verbesserungen-beim-textrendering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>INotifyPropertyChanged &#8211; Varianten f&#252;r die Implementierung</title>
		<link>http://berndhengelein.de/2009/09/inotifypropertychanged-varianten-fr-die-implementierung/</link>
		<comments>http://berndhengelein.de/2009/09/inotifypropertychanged-varianten-fr-die-implementierung/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 19:27:56 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[PostSharp]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=284</guid>
		<description><![CDATA[Wer mit WPF programmiert, kennt INotifyPropertyChanged. Das allgegenwärtige Interface, mit dem Änderungen z.B. von einem ViewModel zu einem daran gebunden UI Element propagiert werden. Eine typische Implementierung von INotifyPropertyChanged sieht etwa so aus:

Drei Sachen fallen ins Auge

jedes ViewModel muss INotifyPropertyChanged implementieren, d.h. den PropertyChanged Event anbieten und eine Methode zum Feuern des Events haben. 
die [...]]]></description>
			<content:encoded><![CDATA[<p>Wer mit WPF programmiert, kennt <a href="http://msdn.microsoft.com/de-de/library/system.componentmodel.inotifypropertychanged(VS.95).aspx">INotifyPropertyChanged</a>. Das allgegenwärtige Interface, mit dem Änderungen z.B. von einem ViewModel zu einem daran gebunden UI Element propagiert werden. Eine typische Implementierung von INotifyPropertyChanged sieht etwa so aus:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="INotifyPropertyChanged Horror" border="0" alt="INotifyPropertyChanged Horror" src="http://berndhengelein.de/wp-content/uploads/2009/09/INotifyPropertyChanged.png" width="616" height="700" /></p>
<p>Drei Sachen fallen ins Auge</p>
<ol>
<li>jedes ViewModel muss INotifyPropertyChanged implementieren, d.h. den PropertyChanged Event anbieten und eine Methode zum Feuern des Events haben. </li>
<li>die EventArgs für den PropertyChanged Event bekommen als Parameter einen <strong>String</strong>, der dem Namen der Property entspricht. </li>
<li>der Code ist “zugemüllt” mit Infrastrukturcode, der eigentlich nichts zur Logik des Objekts beiträgt </li>
</ol>
<ol>Der erste Punkt lässt sich relativ einfach lösen, indem man eine ViewModel Basisklasse macht, die diese Aufgaben übernimmt.</ol>
<ol><strong>Basisklasse für ViewModels</strong></ol>
<ol>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a25e30eb-cdc6-4ed1-9223-a3885f0b7466" class="wlWriterSmartContent">
<pre class="c#:nogutter:nocontrols" name="code">public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}</pre>
</p></div>
</ol>
<p>Beim zweiten Punkt wird es dann schon schwieriger. Hier gibt es mehrere Ansätze, die Strings loszuwerden.</p>
<p>Am häufigsten trifft man wohl eine Variante mit Lambda Expressions an. Die Implementierungen reichen von einer Extensionmethod für den PropertyChangedEventHandler bis zu einer generischen ViewModel Basisklasse, welche das abgeleitete ViewModel als Type Parameter bekommt. Hier ein paar Links zum Nachlesen:</p>
<p><a href="http://www.jphamilton.net/post/MVVM-with-Type-Safe-INotifyPropertyChanged.aspx" target="_blank">J.P. Hamilton &#8211; Generische ViewModel Basisklasse</a></p>
<p><a href="http://www.lieser-online.de/blog/?p=130" target="_blank">Stefan Lieser &#8211; Implementierung direkt im ViewModel</a></p>
<p><a href="http://blog.decarufel.net/2009/07/how-to-use-inotifypropertychanged-type_22.html" target="_blank">Eric De Carufel &#8211; Extensionmethod für PropertyChangedEventHandler</a></p>
<p>&#160;</p>
<p>Andere Lösungen, die ich gefunden habe:</p>
<p><a href="http://www.nablasoft.com/alkampfer/index.php/2008/08/14/how-to-implement-inotifypropertychanged-with-codedom/" target="_blank">Alkampfer &#8211; INotifyPropertyChanged mit CodeDom implementieren</a></p>
<p><a href="http://ayende.com/Blog/archive/2009/08/07/nhibernate-amp-inotifypropertychanged.aspx" target="_blank">Ayende &#8211; INotifyPropertyChanged mit Castle Dynamic Proxy</a></p>
<p><a href="http://thetreeknowseverything.net/2009/01/21/auto-implement-inotifypropertychanged-with-aspects/" target="_blank">Mike Saunders &#8211; INotifyPropertyChanged mit PostSharp Aspekt</a></p>
<p><a href="http://richardsbraindump.blogspot.com/2009/02/aspect-oriented-programming.html" target="_blank">Richard Banks &#8211; INotifyPropertyChanged mit PostSharp Aspekt</a></p>
<p>&#160;</p>
<p>Dann gibt es noch <strike>die</strike> den Verfechter von <a href="http://www.codeplex.com/updatecontrols">UpdateControls</a>, <a href="http://adventuresinsoftware.com/blog/">Michael L. Perry</a>. UpdateControls ist eine Open Source Bibliothek auf <a href="http://www.codeplex.com/">CodePlex</a>, die es erlaubt, Änderungen von Eigenschaften auch ohne INotifyProperyChanged zu propagieren und z.B. an WPF Controls zu binden. Eine <a href="http://www.code-magazine.com/Article.aspx?quickid=0907101">gute Einführung</a> in UpdateControls kann man beim <a href="http://www.code-magazine.com/Index.aspx">CODE Magazin</a> lesen.</p>
<p>&#160;</p>
<p>Mir gefallen bisher die Lösungen mit PostSharp am Besten. Damit lassen sich alle drei Punkte auf einmal erschlagen.</p>
<ol>
<li>Mit einem PostSharp Attribut, das auf die ViewModel Klasse geklebt wird, lässt man die INotifyPropertyChanged Implementierung automatisch einweben. </li>
<li>Es gibt keine Magic Strings mehr, da auch das Feuern des ProperyChanged Events automatisch eingewoben wird. Verschreiber sind dadurch ausgeschlossen, Refactoring ist kein Problem. </li>
<li>Der Code bleibt sauber und lesbar, da der ganze Notifikationscode erst nachträglich hinzugefügt wird. </li>
</ol>
<ol><strong>Der nächste Schritt</strong></ol>
<p>Ein Kollege von mir hatte die Idee, die Verwendung von PostSharp in Verbindung mit dem MVVM Pattern noch einen Schritt weiter zu treiben. Wir verwenden jetzt ein [ViewModelAspekt] PostSharp Attribut, mit dem die ViewModels versehen werden.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:0f090b30-5b83-405e-8483-2c0781406394" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">[ViewModelAspect]
public class MyViewModel
{
    private string _name;

    public string Name
    {
        get{ return _name;}
        set{ _name = value;}
    }

    public void Save()
    {
        // do sth.
    }
}</pre>
</div>
<p>Dieser Aspekt macht folgendes:</p>
<ul>
<li>Implementierung von INotifyPropertyChanged </li>
<li>Für alle public Properties wird im Setter der PropertyChanged Event gefeuert </li>
<li>Für alle public void Methoden wird eine Command Property erzeugt, welche mit Hilfe des <a href="http://dotnet.org.za/rudi/archive/2009/03/05/the-power-of-icommand.aspx">Delegate/Relay Commands</a> wiederum diese Methode aufruft. </li>
</ul>
<ul>Dadurch haben wir es geschafft, den Overhead für die Verwendung des <a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx">MVVM Patterns</a> sehr gering zu halten. Die nächsten Wochen werden zeigen, ob sich diese Variante bewährt und alle Use Cases damit abgedeckt werden können.</ul>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/09/inotifypropertychanged-varianten-fr-die-implementierung/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WPF Grundlagen &#8211; Wie finden Applikation und Fenster zusammen?</title>
		<link>http://berndhengelein.de/2009/07/wpf-grundlagen-wie-finden-applikation-und-fenster-zusammen/</link>
		<comments>http://berndhengelein.de/2009/07/wpf-grundlagen-wie-finden-applikation-und-fenster-zusammen/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 21:40:43 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=273</guid>
		<description><![CDATA[Die Projektvorlagen dieser Welt machen es dem Entwickler heutzutage sehr einfach, zu einer lauffähigen Anwendung zu kommen. Ein paar Klicks und schon ist das Gerüst z.B. für eine WPF Applikation fertig. Dabei passiert aber auch so manches hinter den Kulissen, was auf den ersten Blick nicht so leicht ersichtlich ist. Deswegen stellen wir uns heute [...]]]></description>
			<content:encoded><![CDATA[<p>Die Projektvorlagen dieser Welt machen es dem Entwickler heutzutage sehr einfach, zu einer lauffähigen Anwendung zu kommen. Ein paar Klicks und schon ist das Gerüst z.B. für eine WPF Applikation fertig. Dabei passiert aber auch so manches hinter den Kulissen, was auf den ersten Blick nicht so leicht ersichtlich ist. Deswegen stellen wir uns heute die Frage, wie bei einer vom Visual Studio generierten WPF Anwendung, das Applikationsobjekt und das Hauptfenster zusammenfinden.</p>
<p>Wie sieht die Struktur einer WPF Anwendung aus, die mit dem Projekttemplate von Visual Studio 2008 erstellt wurde?</p>
<p>&#160;<a href="http://berndhengelein.de/wp-content/uploads/2009/07/image.png"><img style="border-right-width: 0px; margin: 0px 15px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Struktur einer WPF Anwendung in VS 2008" border="0" alt="Struktur einer WPF Anwendung in VS 2008" align="left" src="http://berndhengelein.de/wp-content/uploads/2009/07/image_thumb.png" width="281" height="229" /></a> </p>
<p>Der Screenshot zeigt den Aufbau einer solchen WPF Applikation. Es fallen auf Anhieb zwei Teile auf, die jeweils aus einem XAML File und einem C# File bestehen:</p>
<ul>
<li>App.* – beschreiben das Applikationsobjekt </li>
<li>Window1.* – beschreiben das Hauptfenster der Applikation </li>
</ul>
<ul>Und, wie nicht anders zu erwarten, läuft das Programm wenn F5 im Studio gedrückt wird. Aber was passiert hier? Dazu werfen wir einen Blick auf den Sourcecode.</ul>
<p><strong></strong></p>
<p><strong>XAML File für das Haupfenster</strong></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:3a8352f1-e5f9-4790-b0c0-b263cd2e28a4" class="wlWriterEditableSmartContent">
<pre name="code" class="xml:nogutter:nocontrols">&lt;Window x:Class="WpfApplication.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"&gt;
    &lt;Grid&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</pre>
</div>
<p>Hier gibt es nichts spektakuläres zu sehen. Es wird ein Objekt vom Typ <font face="Bitstream Vera Sans Mono">Window</font> definiert, ein paar Eigenschaften wie Titel, Höhe und Breite angegeben und zwei XML Namespaces eingebunden. Interessant ist der Teil “x:Class=”WpfApplication.Window1”. Mit dem Attribut <a href="http://msdn.microsoft.com/en-us/library/ms752309.aspx" target="_blank">x:Class</a> wird angegeben, dass zu diesem XAML Code noch ein weiterer Teil, nämlich der C# Teil gehört. “WpfApplication” gibt hierbei den Namespace und “Window1” den Klassennamen an. Ein Blick in das zugehörige C# File zeigt dann auch eine partielle Klasse Window1.</p>
<p><strong>C# File für das Hauptfenster</strong></p>
</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:26f3101d-e04a-451f-b149-653e89fe1ad2" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">using System.Windows;

namespace WpfApplication
{
    /// &lt;summary&gt;
    /// Interaction logic for Window1.xaml
    /// &lt;/summary&gt;
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}</pre>
</div>
<p>Bei einem frisch erstellten Projekt ist diese Code-Behind Datei bis auf den Aufruf von “InitializeComponent()” ziemlich leer (die überflüssigen “using” Anweisungen habe ich gleich vom Resharper entfernen lassen).</p>
<p>&#160;</p>
<p><strong>XAML File für die Applikation</strong></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:066e3218-c89a-4491-bcd6-dc8ebf1b6583" class="wlWriterEditableSmartContent">
<pre name="code" class="xml:nogutter:nocontrols">&lt;Application x:Class="WpfApplication.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml"&gt;
    &lt;Application.Resources&gt;
    &lt;/Application.Resources&gt;
&lt;/Application&gt;
</pre>
</div>
<p>Der Aufbau ist ähnlich wie bei dem <font face="Bitstream Vera Sans Mono">Window</font>. Hier taucht erstmals eine Verbindung zwischen der Applikation und dem Fenster auf, indem das <font face="Bitstream Vera Sans Mono">StartupUri</font> Attribut auf den Dateinamen des XAML Files des Fensters gesetzt wird.</p>
<p><strong></strong></p>
<p><strong>C# File für die Applikation</strong></p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1d40921f-13ad-4aa0-bc55-52ac5a29e3e8" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">using System.Windows;

namespace WpfApplication
{
    /// &lt;summary&gt;
    /// Interaction logic for App.xaml
    /// &lt;/summary&gt;
    public partial class App : Application
    {
    }
}</pre>
</div>
<p>Hier herrscht gähnende Leere. Die partielle Klasse des Applikationsobjektes ist komplett leer. Jetzt stellt sich die Frage, wo denn die “Main” Methode unserer Applikation ist. Irgendwie muss die Anwendung ja gestartet werden. Hier hilft uns der “Show All Files” Button im Solution Explorer weiter:</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/07/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Show all files in Solution Explorer" border="0" alt="Show all files in Solution Explorer" src="http://berndhengelein.de/wp-content/uploads/2009/07/image_thumb1.png" width="367" height="465" /></a> </p>
<p>Jetzt werden auch alle temporären Dateien angezeigt, die während des Kompiliervorgangs entstanden sind. Aus dieser Vielzahl sehen wir uns ein File ein bisschen genauer an:</p>
<p><strong>App.g.cs</strong></p>
<p>Das ‘g’ im Dateinamen steht für “generated”. Es handelt sich hier also um einen generierten Teil der Applikationsklasse. Ich picke mal den interessanten Teil heraus:</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:20980b45-e4bb-40ca-b437-e5901d4737fd" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">...
public void InitializeComponent() {

    #line 4 "..\..\App.xaml"
    this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);

    #line default
    #line hidden
}

/// &lt;summary&gt;
/// Application Entry Point.
/// &lt;/summary&gt;
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
    WpfApplication.App app = new WpfApplication.App();
    app.InitializeComponent();
    app.Run();
}
...</pre>
</div>
<p>Et voilà, hier findet sich auch eine <font face="Bitstream Vera Sans Mono">Main()</font> Methode welche den Einstiegspunkt für das Programm darstellt. In InitializeComponent() findet sich auch wieder die <a href="Show all files in Solution Explorer" target="_blank">StartupUri</a> Eigenschaft, die in App.xaml gesetzt wurde. Durch das setzen dieser Eigenschaft wird das von der URI referenzierte Fenster beim Start der Applikation angezeigt und als dessen Hauptfenster gesetzt (ist also über <font face="Bitstream Vera Sans Mono">Application.Current.MainWindow</font> erreichbar).</p>
<p>Auch wenn es den erfahrenen WPF Entwickler vielleicht gelangweilt haben mag &#8211; ich finde solche Grundlagen wichtig. Eventuell war ja für den einen oder anderen WPF Einsteiger etwas Neues/Interessantes dabei.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/07/wpf-grundlagen-wie-finden-applikation-und-fenster-zusammen/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>.NET Open Space S&#252;d 2009</title>
		<link>http://berndhengelein.de/2009/07/net-open-space-sd-2009/</link>
		<comments>http://berndhengelein.de/2009/07/net-open-space-sd-2009/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 18:56:28 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Verschiedenes]]></category>
		<category><![CDATA[Community]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=263</guid>
		<description><![CDATA[
    


Wow! Das war wirklich ein gelungenes Wochenende. Die Rede ist vom ersten .NET Open Space Süd, welcher vom 11.09. – 12.09. in Blaustein bei Ulm stattfand. Nach dem Vorbild der ALT.NET Konferenz in London und dem .NET Open Space in Leipzig haben Thomas Schissler und Alexander Zeitler auch für den Süden [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ulm.netopenspace.de/" title=".NET Open Space Süd vom 11.07. bis 12.07.2009 in Ulm"><br />
    <img src="http://ulm.netopenspace.de/2009/GetFile.aspx?File=Logos/nos-logo-5-2009.png" alt=".NET Open Space vom 11.07. bis 12.07.2009 in Ulm" /><br />
</a>
</p>
<p>Wow! Das war wirklich ein gelungenes Wochenende. Die Rede ist vom ersten <a href="http://ulm.netopenspace.de/2009/">.NET Open Space Süd</a>, welcher vom 11.09. – 12.09. in Blaustein bei Ulm stattfand. Nach dem Vorbild der <a href="http://www.altnetuk.com/">ALT.NET Konferenz in London</a> und dem <a href="http://netopenspace.de/2009/">.NET Open Space in Leipzig</a> haben <a href="http://www.artiso.com/problog/">Thomas Schissler</a> und <a href="http://blog.alexonasp.net/">Alexander Zeitler</a> auch für den Süden der Republik eine Communityveranstaltung der besonderen Art organisiert.</p>
<p>Eine Konferenz ohne Agenda, ohne geplante Vorträge? Kann das funktionieren? Ja, und zwar sehr gut! Die Teilnehmer organisieren sich selbst, machen Themenvorschläge und finden sich dann in Gruppen zusammen um die Themen zu diskutieren. Eine wunderbare Abwechslung zur Berieselung bei den herkömmlichen Veranstaltungen. In Ulm haben auf diese Weise ca. 60 Teilnehmer ihr Wissen und ihre Erfahrung ausgetauscht.</p>
<p>Dabei wurden sowohl technische Themen wie ASP.Net MVC, WPF, ORM, AOP,… unter die Lupe genommen als auch Bereiche wie SCRUM oder Getting Things Done ausführlich diskutiert. Danke an alle Teilnehmer, durch die solch ein Event erst möglich wird.</p>
<p>Um den Kopf wieder frei zu bekommen, darf natürlich auch ein entsprechendes Rahmenprogramm nicht fehlen. Auch hier haben sich Thomas und Alex nicht lumpen lassen und haben uns den Abend mit Bauchtanz und Feuershow verschönt. Wenn dann auch noch das Catering vom lokalen Sportverein so perfekt vonstatten geht, gibt’s wirklich nichts zu meckern.</p>
<p>Wer sich ein Bild machen möchte, findet Bilderserien dazu von <a href="http://www.aspnetzone.de/blogs/peterbucher/default.aspx">Peter</a>, <a href="http://blog.jan-welker.de/default.aspx">Jan</a> und <a href="http://der-albert.com/">Albert</a> <a href="http://cid-58b8038555f39d35.skydrive.live.com/browse.aspx/NetOS|_S%C3%BCd?ct=photos">hier</a>, <a href="http://cid-7e1203b1f022be53.skydrive.live.com/browse.aspx/NetOS|_S%C3%BCd?ct=photos">hier</a> und <a href="http://cid-178f1647bbfe2b9f.skydrive.live.com/browse.aspx/NET%20Open%20Space%20S%C3%BCd%202009">hier</a>. Weiteres Feedback und zusätzliche Informationen gibt es auf dem <a href="http://ulm.netopenspace.de/2009/Schwarzes%20Brett.ashx">Schwarzen Brett</a>.</p>
<p>Bis zum nächsten .NET Open Space – vielleicht schon in Leipzig.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/07/net-open-space-sd-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wie kriege ich mit, ob der Rechner gelockt wird?</title>
		<link>http://berndhengelein.de/2009/06/wie-kriege-ich-mit-ob-der-rechner-gelockt-wird/</link>
		<comments>http://berndhengelein.de/2009/06/wie-kriege-ich-mit-ob-der-rechner-gelockt-wird/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 20:31:33 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=257</guid>
		<description><![CDATA[Ja, ja, wenn man es mal weiß, dann ist alles einfach und sonnenklar.&#160; Ich wollte vor kurzem wissen, wie ich in einem Programm darauf reagieren kann, wenn der Computer gesperrt/gelockt wird. Das rauszufinden, hat überraschenderweise recht lange gedauert. Dabei hätte ich nur nach “SystemEvents” googeln müssen. Aber das wusste ich zu dem Zeitpunkt natürlich nicht.
Die [...]]]></description>
			<content:encoded><![CDATA[<p>Ja, ja, wenn man es mal weiß, dann ist alles einfach und sonnenklar.&#160; Ich wollte vor kurzem wissen, wie ich in einem Programm darauf reagieren kann, wenn der Computer gesperrt/gelockt wird. Das rauszufinden, hat überraschenderweise recht lange gedauert. Dabei hätte ich nur nach “<a href="http://msdn.microsoft.com/de-de/library/microsoft.win32.systemevents_events.aspx" target="_blank">SystemEvents</a>” googeln müssen. Aber das wusste ich zu dem Zeitpunkt natürlich nicht.</p>
<p>Die SystemEvents Klasse aus dem Microsoft.Win32 Namespace bietet einen Sack voll Events an, um auf Systemereignisse reagieren zu können. Unter anderem gibt es ein <a href="http://msdn.microsoft.com/de-de/library/microsoft.win32.systemevents.sessionswitch.aspx" target="_blank">SessionSwitch</a> Event:</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/06/image.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="183" alt="image" src="http://berndhengelein.de/wp-content/uploads/2009/06/image_thumb.png" width="598" border="0" /></a></p>
<p>Mit einem kleinen Testprogramm sieht man auch sofort, dass dieses Event gefeuert wird, wenn der Computer gesperrt wird:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7828c724-75cb-4936-ba7c-cdb610040ebc" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">static void Main(string[] args)
{
    SystemEvents.SessionSwitch +=
    	(s, e) =&gt; Console.WriteLine("Event {0} received...",
                                	e.Reason);
    Console.ReadLine();
}</pre>
</div>
<p>Ein Sperren und Entsperren ergibt folgende Ausgabe:</p>
<blockquote>
<p>Event SessionLock received&#8230;<br />
    <br />Event SessionUnlock received&#8230;</p>
</blockquote>
<p>War doch gar nicht so schwer. Im realen Leben solltet ihr aber auf keinen Fall vergessen euch wieder von dem Event abzumelden. Ansonsten kann das Objekt, welches sich an dem Event angemeldet hat, nicht vom Garbage Collector abgeräumt werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/06/wie-kriege-ich-mit-ob-der-rechner-gelockt-wird/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fünf Freunde: Action, Predicate, Comparison, Converter und Lambda Ausdrücke</title>
		<link>http://berndhengelein.de/2009/05/funf-freunde-action-predicate-comparison-converter-und-lambda-ausdrucke/</link>
		<comments>http://berndhengelein.de/2009/05/funf-freunde-action-predicate-comparison-converter-und-lambda-ausdrucke/#comments</comments>
		<pubDate>Thu, 21 May 2009 21:53:09 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=249</guid>
		<description><![CDATA[Ich habe den Eindruck, dass die generischen Delegates aus dem .Net Framework vielerorts immer noch ein Schattendasein fristen. Mit ein paar einfachen Beispielen die zeigen, wofür man Action, Predicate und Co. verwenden kann, möchte ich Lust auf mehr machen. 
Generische Delegates ersparen dem Entwickler die Arbeit eigene Delegates zu deklarieren und kommen häufig in Verbindung [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe den Eindruck, dass die generischen Delegates aus dem .Net Framework vielerorts immer noch ein Schattendasein fristen. Mit ein paar einfachen Beispielen die zeigen, wofür man Action, Predicate und Co. verwenden kann, möchte ich Lust auf mehr machen. </p>
<p>Generische Delegates ersparen dem Entwickler die Arbeit eigene Delegates zu deklarieren und kommen häufig in Verbindung mit Containerklassen zur Anwendung.</p>
<p>Als Spielzeugklasse habe ich mir diesmal etwas ganz aussergewöhnliches einfallen lassen. Und zwar eine Klasse Person:</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c38616e5-7ac5-4f8f-8a9d-5393c55847f9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsCool { get; set; }

    public override string ToString()
    {
        return String.Format( "{0} is {1}.", Name, IsCool ? "cool" : "not cool" );
    }
}</pre>
</div>
<p>Dazu erzeugen wir uns noch ein paar &quot;Versuchspersonen&quot;:</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:56e6d8ea-b3a8-4582-bb15-04b5a0774cf1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">List&lt;Person&gt; persons = new List&lt;Person&gt;();

persons.Add( new Person {Name = "Karin", Age = 39} );
persons.Add( new Person {Name = "Simon", Age = 23} );
persons.Add( new Person {Name = "Fritz", Age = 34} );
persons.Add( new Person {Name = "Georg", Age = 56} );
persons.Add( new Person {Name = "Susi", Age = 67} );
persons.Add( new Person {Name = "Toni", Age = 45} );</pre>
</div>
<p><strong>Action&lt;T&gt; Delegate</strong></p>
<p>Der Action&lt;T&gt; Delegate kapselt eine Methode die einen Parameter übergeben bekommt und keinen Wert zurückgibt. Mit .Net 3.5 wurden noch zusätzliche Action Delegates eingeführt, die bis zu vier Parameter bekommen (Action&lt;T1, T2&gt;, Action&lt;T1, T2, T3&gt; und Action&lt;T1, T2, T3, T4&gt;).</p>
<p>Ein Action Delegate wird z.B. als Parameter für die ForEach Methode der Klasse List&lt;T&gt; benötigt. ForEach iteriert über die gesamte Liste und führt für jedes Element die übergebene Methode aus.</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/05/image.png"><img title="Action&lt;T&gt; delegate" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="84" alt="Action&lt;T&gt; delegate" src="http://berndhengelein.de/wp-content/uploads/2009/05/image-thumb.png" width="554" border="0" /></a> </p>
<p>Hier ein paar Beispiele: </p>
<p>Informationen über alle unsere Personen auf der Console ausgeben:</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9571ca42-31d6-4343-aec8-8b396bb42f96" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">persons.ForEach(Console.WriteLine);</pre>
</div>
<p>In Verbindung mit einem Lambdaausdruck werden alle Personen ganz schnell cool:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:dd11ad82-c628-490b-a41c-b12f3b7dd361" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">persons.ForEach(p =&gt; p.IsCool = true);</pre>
</div>
<p><strong>Predicate&lt;T&gt; Delegate</strong></p>
<p>Der Predicate&lt;T&gt; Delegate kapselt eine Methode die einen Parameter (vom Typ T) übergeben bekommt und <em>true</em> oder <em>false</em> zurückgibt. Es steckt aber auch Semantik in dem Predicate Delegate: er definiert einen Satz von Kriterien und überprüft ob das übergebene Objekt diese Kriterien erfüllt. Das klingt erstmal ziemlich geschwollen, aber ein Beispiel macht das schnell klar.</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/05/image1.png"><img title="Predicate&lt;T&gt; delegate" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="100" alt="Predicate&lt;T&gt; delegate" src="http://berndhengelein.de/wp-content/uploads/2009/05/image-thumb1.png" width="657" border="0" /></a> </p>
</p>
<p>Um z.B. alle Personen die älter als 50 sind zu entfernen, schreiben wir:</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:23ab3e0e-895e-4add-b3a4-e021c6580c95" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">persons.RemoveAll( p =&gt; p.Age &gt; 50 );</pre>
</div>
<p>Mit der Methode Exists kann überprüft werden, ob in der Liste Element enhalten sind, die eine bestimmte Bedingung erfüllen:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:66d033f0-c348-4a81-97d8-7d63c709b26a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">if (persons.Exists(p =&gt; p.Name == "Toni"))
{
    Console.WriteLine("A person with name Toni exists");
}</pre>
</div>
<p><strong>Comparison&lt;T&gt; Delegate</strong></p>
<p>Der Comparison&lt;T&gt; Delegate kapselt eine Methode die zwei Objekte gleichen Typs vergleicht.</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:22426398-c5f7-416f-9294-deeb253ca528" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">public delegate int Comparison&lt;T&gt;
(
	T x,
	T y
)
</pre>
</div>
<p>Als Rückgabewert dient ein Integer der anzeigt, ob die beiden Objekte gleich sind:</p>
<table cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="199"><strong>Rückgabewert</strong></td>
<td valign="top" width="199"><strong>Bedingung</strong></td>
</tr>
<tr>
<td valign="top" width="199">Kleiner als 0</td>
<td valign="top" width="199">x ist kleiner als y</td>
</tr>
<tr>
<td valign="top" width="199">0</td>
<td valign="top" width="199">x und y sind gleich</td>
</tr>
<tr>
<td valign="top" width="199">Größer als 0</td>
<td valign="top" width="199">x ist größer als y</td>
</tr>
</tbody>
</table>
<p> Um die Liste von Personen nach dem Alter aufsteigend zu sortieren, übergebe ich der <em>Sort()</em> Methode einen Comparison Delegate:</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/05/image2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="143" alt="image" src="http://berndhengelein.de/wp-content/uploads/2009/05/image-thumb2.png" width="563" border="0" /></a> </p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2d14bf95-db91-4339-8aba-963291ce07b3" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">persons.Sort( (person1, person2) =&gt; person1.Age.CompareTo( person2.Age ) );</pre>
</div>
<p><strong></strong></p>
<p><strong>Converter&lt;TInput, TOutput&gt; Delegate</strong></p>
<p>Der Converter&lt;TInput, TOutput&gt; Delegate repräsentiert eine Methode die ein Objekt vom Typ TInput als Parameter bekommt und ein Objekt vom Typ TOutput zurückgibt. Der Hauptanwendungsfall ist das Konvertieren von Elementen in einem Array oder einer Liste.</p>
<p>Die Liste von Personen kann z.B. einfach in eine Liste von Namen konvertiert werden:</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:50972c95-fc64-48a5-a6ee-757f07275b82" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:nogutter:nocontrols">List&lt;string&gt; names = persons.ConvertAll( p =&gt; p.Name );</pre>
</div>
<p>Durch das Naming der Methode <em>ConvertAll</em> geht auch sehr schön hervor, dass es sich um eine Konvertierung handelt. Dadurch entsteht lesbarer, verständlicher Code.</p>
<p>&#160;</p>
<p>Die generischen Delegates des.Net Frameworks, bieten eine elegante Möglichkeit mit den Containerklassen zu arbeiten. Durch die Verwendung von Lambda Ausdrücken führt das Finden, Sortieren usw. von Listen zur sehr schönem, lesbaren Code. Ich finde die generischen Delegates klasse!</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/05/funf-freunde-action-predicate-comparison-converter-und-lambda-ausdrucke/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

