<?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; WPF</title>
	<atom:link href="http://berndhengelein.de/tag/wpf/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>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>Rahmenlose Fenster mit WPF</title>
		<link>http://berndhengelein.de/2009/04/rahmenlose-fenster-mit-wpf/</link>
		<comments>http://berndhengelein.de/2009/04/rahmenlose-fenster-mit-wpf/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 18:44:37 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=222</guid>
		<description><![CDATA[ 
Achtung, das folgende Beispiel bringt wahrscheinlich keinen Nutzen für den täglichen Umgang mit WPF!
EGAL! Manchmal muss man eben auch spielen  . Rahmenlose Fenster sind einfach cool. Wenn dann auch noch ein guter Designer mit im Spiel ist, sieht das Ganze auch besser aus als bei meinem Versuch.
Ok, Design beiseite. Was ist zu tun [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://berndhengelein.de/wp-content/uploads/2009/04/nonrectwindow-new1.png"><img title="NonRectWindow" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 15px 15px 0px; border-right-width: 0px" height="215" alt="NonRectWindow" src="http://berndhengelein.de/wp-content/uploads/2009/04/nonrectwindow-new-thumb1.png" width="215" align="left" border="0" /></a> </p>
<p>Achtung, das folgende Beispiel bringt wahrscheinlich keinen Nutzen für den täglichen Umgang mit WPF!</p>
<p>EGAL! Manchmal muss man eben auch spielen <img src='http://berndhengelein.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Rahmenlose Fenster sind einfach cool. Wenn dann auch noch ein guter Designer mit im Spiel ist, sieht das Ganze auch besser aus als bei meinem Versuch.</p>
<p>Ok, Design beiseite. Was ist zu tun um eine Anwendung mit einem rahmenlosen Fenster zu erstellen?</p>
<p> Der erste Schritt besteht darin, an dem Fenster der Applikation drei Eigenschaften entsprechend zu setzen:</p>
<ul>
<li><em>AllowsTransparency</em> auf <em>true</em> </li>
<li><em>WindowStyle</em> auf <em>None – </em>in Verbindung mit <em>AllowsTransparency=”True”</em> wird erreicht, dass der Fensterrahmen und die Titelzeile verschwinden </li>
<li><em>Background</em> auf <em>Transparent</em>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9cb4b206-4d7f-4be6-b1d4-73d4b8cbf196" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="xml:nogutter:nocontrols">&lt;Window x:Class="NonRectShapedWindowWPF.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="215"
    Height="215"
    AllowsTransparency="True"
    WindowStyle="None"
    Background="Transparent"&gt;
...</pre>
</div>
<p>In meinem Beispiel habe ich mich dazu entschieden das UI aus zwei Kreisen zusammenzusetzen. Der grosse Kreis dient als “Hauptrahmen” der Anwendung und der kleine Kreis enthält einen “Close” Button. </li>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:c472a9b8-8b38-4010-916d-ea67003c181f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="xml:nogutter:nocontrols">...
&lt;Grid Height="200" Width="200"&gt;
    &lt;Ellipse Fill="Red" Stroke="DarkRed"
             MouseLeftButtonDown="OnCircleMouseLeftButtonDown"&gt;
        &lt;Ellipse.BitmapEffect&gt;
            &lt;OuterGlowBitmapEffect GlowSize="8" GlowColor="OrangeRed" /&gt;
        &lt;/Ellipse.BitmapEffect&gt;
    &lt;/Ellipse&gt;

    &lt;Canvas...&gt;

    &lt;Button Margin="150 -150 0 0"
            Template="{StaticResource closeButton}"
            FontFamily="Webdings"
            FontWeight="Bold"
            FontSize="10"
            Content="r"
            Click="OnCloseButtonClick"
            ToolTip="Close"&gt;
    &lt;/Button&gt;
&lt;/Grid&gt;
...</pre>
</div>
</ul>
<p>Der eigentliche Inhalt der Anwendung versteckt sich in dem zusammengeklappten &lt;<em><a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.aspx" target="_blank">Canvas</a></em>&gt; Element. Die Details dazu gibt es weiter unten.</p>
<p>Wie in dem XAML Code zu sehen ist, wird der “Close” Button über die Margin Eigenschaft an der gewünschten Stelle positioniert. Um dem Button ein rundes Aussehen zu verpassen, habe ich ein <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx" target="_blank">ControlTemplate</a> erstellt.</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2bb5d9da-bac1-4cac-b04e-d49ef7136588" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="xml:nogutter:nocontrols">...
&lt;ControlTemplate x:Key="closeButton" TargetType="{x:Type Button}"&gt;
    &lt;Grid&gt;
        &lt;Ellipse Fill="Red" Stroke="DarkRed"
                 Width="25" Height="25"/&gt;

        &lt;Label Content="{TemplateBinding Content}"
               Foreground="Black"
               HorizontalAlignment="Center" VerticalAlignment="Center"/&gt;
    &lt;/Grid&gt;
&lt;/ControlTemplate&gt;
...</pre>
</div>
<p>Um dem Anwender ein Verschieben des Fensters zu ermöglichen, fügt man einen Eventhandler für das <em>MouseLeftButtonDown</em> Event hinzu. Und zwar an dem Element, mit dem das Fenster verschoben werden soll. Das könnte z.B. eine eigene Titelleiste sein, oder wie bei mir irgendein anderes, sichtbares Element. Der Code in dem Eventhandler ist sehr einfach:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:95cfd2e8-2bed-45c4-8958-0c2c7e1179b9" 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">private void OnCircleMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    DragMove();
}</pre>
</div>
<p>Ein weiterer Eventhandler wird für das Click Event unseres “Close” Buttons benötigt um das Fenster zu schliessen:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e8c6b9ac-64b3-49a2-ba69-416377674000" 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">private void OnCloseButtonClick(object sender, RoutedEventArgs e)
{
    Close();
}</pre>
</div>
<p>Damit sind die wichtigsten Schritte gemacht, um ein rahmenloses Fenster mit WPF zu erstellen. Es kann vom Anwender verschoben und geschlossen werden. Um ein bisschen Action in das Beispiel zu bringen, gibt es noch eine kleine Animation, die Text durch das Fenster scrollen lässt. Der Code dazu sieht so aus:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:3640bf0c-f00e-4f67-bdde-99a3fb1d7f4e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="xml:nogutter:nocontrols">...
&lt;Canvas Height="100" Width="120" ClipToBounds="True"&gt;
    &lt;TextBlock x:Name="_text"
               Height="100" Width="120"
               VerticalAlignment="Center" HorizontalAlignment="Center"
               TextWrapping="Wrap"
               FontFamily="Tahoma" FontSize="12"&gt;
            &lt;TextBlock.Text&gt;
                Diese Anwendung ist völlig sinnlos. Zu nichts zu gebrauchen. Und doch hat es viel Spass
                gemacht sie zu erstellen.
            &lt;/TextBlock.Text&gt;
            &lt;TextBlock.Triggers&gt;
                &lt;EventTrigger RoutedEvent="TextBlock.Loaded" &gt;
                  &lt;BeginStoryboard&gt;
                    &lt;Storyboard&gt;
                      &lt;DoubleAnimation
                        Storyboard.TargetName="_text"
                        Storyboard.TargetProperty="(Canvas.Top)"
                        Duration="0:0:4"
                        From="110" To="-80"
                        RepeatBehavior="Forever"/&gt;
                    &lt;/Storyboard&gt;
                    &lt;/BeginStoryboard&gt;
                &lt;/EventTrigger&gt;
            &lt;/TextBlock.Triggers&gt;
    &lt;/TextBlock&gt;
&lt;/Canvas&gt;
...</pre>
</div>
<p>Das komplette Beispiel kann hier heruntergeladen werden:</p>
<p><iframe style="border-right: #dde5e9 1px solid; padding-right: 0px; border-top: #dde5e9 1px solid; padding-left: 0px; padding-bottom: 0px; margin: 3px; border-left: #dde5e9 1px solid; width: 240px; padding-top: 0px; border-bottom: #dde5e9 1px solid; height: 66px; background-color: #ffffff" marginwidth="0" marginheight="0" src="http://cid-a575d63718548aa9.skydrive.live.com/embedrowdetail.aspx/Public/Examples%20from%20blog/NonRectShapedWindowWPF.zip" frameborder="0" scrolling="no"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/04/rahmenlose-fenster-mit-wpf/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Databinding und Validierung in WPF – Validation Rules</title>
		<link>http://berndhengelein.de/2009/03/databinding-und-validierung-in-wpf-%e2%80%93-validation-rules/</link>
		<comments>http://berndhengelein.de/2009/03/databinding-und-validierung-in-wpf-%e2%80%93-validation-rules/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 21:30:11 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=135</guid>
		<description><![CDATA[In dem letzten Posting zu dem Thema habe ich einige Vorbereitungen getroffen, um Data Validation unter die Lupe zu nehmen. Eine simple Beispielanwendung wurde vorgestellt, die als Basis für weitere Untersuchungen dient. Diesmal geht es um
Validation Rules
Hier eine Übersicht der eingebauten Validation Rules:

Validation Rules werden direkt am Binding angegeben. Für die beiden mitgelieferten Rules gibt [...]]]></description>
			<content:encoded><![CDATA[<p>In dem <a href="http://berndhengelein.de/2009/01/databinding-und-validierung-in-wpf-erste-vorbereitungen/">letzten Posting</a> zu dem Thema habe ich einige Vorbereitungen getroffen, um Data Validation unter die Lupe zu nehmen. Eine simple Beispielanwendung wurde vorgestellt, die als Basis für weitere Untersuchungen dient. Diesmal geht es um</p>
<p><strong>Validation Rules</strong></p>
<p>Hier eine Übersicht der eingebauten Validation Rules:</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/02/classdiagramvalidationrules.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ClassDiagramValidationRules" border="0" alt="ClassDiagramValidationRules" src="http://berndhengelein.de/wp-content/uploads/2009/02/classdiagramvalidationrules-thumb.png" width="427" height="271" /></a></p>
<p>Validation Rules werden direkt am Binding angegeben. Für die beiden mitgelieferten Rules gibt es zwei Möglichkeiten diese zu aktivieren.</p>
<p>Einmal über die Eigenschaft ValidationRules:</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:08e2cd35-86b0-40bc-b731-2f48c98c0018" class="wlWriterSmartContent">
<pre class="xml:nogutter:nocontrols" name="code">...
&lt;TextBox.Text&gt;
    &lt;Binding Source=&quot;{StaticResource cd}&quot;
             Path=&quot;Year&quot;
             UpdateSourceTrigger=&quot;PropertyChanged&quot;&gt;
        &lt;Binding.ValidationRules&gt;
            &lt;ExceptionValidationRule/&gt;
            &lt;DataErrorValidationRule/&gt;
        &lt;/Binding.ValidationRules&gt;
    &lt;/Binding&gt;
&lt;/TextBox.Text&gt;
...</pre>
</div>
<p>Oder explizit über die beiden Eigenschaften ValidatesOnExceptions und ValidatesOnDataErrors:</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:03f8395f-376d-44bf-b4a0-34bab103ed63" class="wlWriterSmartContent">
<pre class="xml:nogutter:nocontrols" name="code">...
&lt;TextBox.Text&gt;
    &lt;Binding Source=&quot;{StaticResource cd}&quot;
             Path=&quot;Year&quot;
             UpdateSourceTrigger=&quot;PropertyChanged&quot;
             ValidatesOnExceptions=&quot;True&quot;
             ValidatesOnDataErrors=&quot;True&quot;&gt;
    &lt;/Binding&gt;
&lt;/TextBox.Text&gt;
...</pre>
</div>
<div>Zur Erinnerung: in dem Beispiel aus dem vorherigen Posting ist eine Exception aufgetreten, wenn alle Zeichen in der TextBox gelöscht wurden. Hier kommt die ExceptionValidationRule ins Spiel. Diese Regel fängt alle Exceptions ab, die während der Aktualisierung der Datenquelle auftreten. Schauen wir uns also an, was passiert wenn in dem Beispiel diese Regel aktiviert wird.</div>
<div>&#160;</div>
<div><a href="http://berndhengelein.de/wp-content/uploads/2009/03/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ExceptionValidationRule aktiv" border="0" alt="ExceptionValidationRule aktiv" src="http://berndhengelein.de/wp-content/uploads/2009/03/image-thumb1.png" width="404" height="134" /></a></div>
<p>&#160;</p>
<p>WPF teilt uns mit, dass ein ungültiger Wert eingegeben wurde, indem ein roter Rahmen um die TextBox gezeichnet wird. Das ist die Standardvisualisierung von WPF um Validierungsfehler anzuzeigen.</p>
<p><strong>ErrorTemplates</strong></p>
<p>Mit Hilfe eines eigenen ErrorTemplates ist es möglich, dem Anwender eine hilfreichere Visualisierung für Eingabefehler zu bieten. Das könnte z.B. so aussehen:</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/03/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ExceptionValidationRule mit eigenem ErrorTemplate aktiv" border="0" alt="ExceptionValidationRule mit eigenem ErrorTemplate aktiv" src="http://berndhengelein.de/wp-content/uploads/2009/03/image-thumb2.png" width="404" height="134" /></a></p>
<p>Aha, zumindest wird jetzt ein erklärender Text angezeigt. Die Wortwahl gefällt mir noch nicht besonders, was daran liegt, dass einfach nur der Exceptiontext der gefangenen FormatException angezeigt wird. Das werden wir später ändern. Wie sieht nun das ErrorTemplate aus?</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:c6e6a3dd-e219-4b18-9bc7-fa0df99f42a9" class="wlWriterSmartContent">
<pre class="xml:nogutter:nocontrols" name="code">...
&lt;ControlTemplate x:Key=&quot;TextBoxErrorTemplate&quot;&gt;
    &lt;DockPanel&gt;
        &lt;TextBlock Margin=&quot;0 0 5 0&quot;
                   Text=&quot;!&quot;
                   FontSize=&quot;14&quot;
                   FontWeight=&quot;Bold&quot;
                   Foreground=&quot;Red&quot;/&gt;

        &lt;AdornedElementPlaceholder x:Name=&quot;adornedElement&quot;/&gt;

        &lt;TextBlock Text=&quot;{Binding ElementName=adornedElement,
                                  Path=AdornedElement.(Validation.Errors),
                                  Converter = {local:ValidationErrorToErrorMessageConverter}}&quot;
                   FontSize=&quot;12&quot;
                   Foreground=&quot;Red&quot;
                   Margin=&quot;5 0 0 0&quot;/&gt;
    &lt;/DockPanel&gt;
&lt;/ControlTemplate&gt;
...</pre>
</div>
<p>Im Mittelpunkt steht das zu dekorierende Element (in diesem Fall die TextBox). Über das Tag <a href="http://msdn.microsoft.com/de-de/library/system.windows.controls.adornedelementplaceholder.aspx" target="_blank">AdornedElementPlaceholder</a> bestimmt man, an welcher Stelle im Template dieses Element platziert werden soll. Mit Hilfe eines DockPanels wird zuerst das rote Ausrufezeichen, dann die TextBox und zum Schluss noch ein TextBlock mit dem Fehlertext angezeigt. Der Fehlertext wird über Databinding von der Attached Property <a href="http://msdn.microsoft.com/de-de/library/system.windows.controls.validation.errors.aspx" target="_blank">Validation.Errors</a> der TextBox geholt. Das Databinding System fügt dieser Liste ein ValidationError Objekt hinzu, wenn eine Validation Rule einen Fehler zurückgibt.</p>
<p>Zusätzlich wird hier noch ein Value Converter verwendet. Dieser bringt die Fehler aus der Liste der ValidationErrors in ein lesbares Format (siehe hierzu auch <a href="http://joshsmithonwpf.wordpress.com/2008/10/08/binding-to-validationerrors0-without-creating-debug-spew/">Josh Smith’s Post</a> für eine andere Variante). Der Code hierzu sieht so aus:</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:6981aa18-ed41-4093-8e14-1026ae564146" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">[ValueConversion(typeof(ReadOnlyObservableCollection&lt;ValidationError&gt;), typeof(string))]
public class ValidationErrorToErrorMessageConverter : MarkupExtension, IValueConverter
{
    private ValidationErrorToErrorMessageConverter _mySelf;

    public override object ProvideValue( IServiceProvider serviceProvider )
    {
        if (_mySelf == null)
        {
            _mySelf = new ValidationErrorToErrorMessageConverter();
        }
        return _mySelf;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ReadOnlyObservableCollection&lt;ValidationError&gt; errors =
            value as ReadOnlyObservableCollection&lt;ValidationError&gt;;

        StringBuilder errorMessage = new StringBuilder();
        if(null != errors)
        {
            foreach (var error in errors)
            {
                errorMessage.AppendLine(error.ErrorContent.ToString());
            }

            return errorMessage;
        }

        return errorMessage;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}</pre>
</div>
<p>Der Value Converter leitet sich zusätzlich noch von MarkupExtension ab. Dadurch ist es nicht mehr nötig den Converter als Ressource anzugeben, sondern dieser kann direkt über die Markupextension Syntax verwendet werden (danke an Dr. WPF für diesen <a href="http://www.drwpf.com/blog/Home/tabid/36/EntryID/48/Default.aspx">Tipp</a>).</p>
<p>Das ErrorTemplate wird der TextBox folgendermaßen bekanntgemacht gemacht (siehe Zeile 5):</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:c15417bc-d5ee-4258-8efa-0c43777f86e9" class="wlWriterSmartContent">
<pre class="xml:nocontrols" name="code">...
&lt;TextBox ToolTip=&quot;Please enter year of release&quot;
         Width=&quot;60&quot;
         Margin=&quot;10&quot;
         Validation.ErrorTemplate=&quot;{StaticResource TextBoxErrorTemplate}&quot;&gt;
    &lt;TextBox.Text&gt;
        &lt;Binding Source=&quot;{StaticResource cd}&quot;
                 Path=&quot;Year&quot;
                 UpdateSourceTrigger=&quot;PropertyChanged&quot;
                 ValidatesOnExceptions=&quot;True&quot;&gt;
        &lt;/Binding&gt;
    &lt;/TextBox.Text&gt;
&lt;/TextBox&gt;
...</pre>
</div>
<p><strong>Selbstgeschriebene Validation Rules</strong></p>
<p>Zusätzlich zu den mitgelieferten Validation Rules hat man natürlich die Möglichkeit eigene Rules zu implementieren. Dazu wird die eigene Klasse von <a href="http://msdn.microsoft.com/de-de/library/system.windows.controls.validationrule.aspx">ValidationRule</a> abgeleitet und die Methode <a href="http://msdn.microsoft.com/de-de/library/system.windows.controls.validationrule.validate.aspx">Validate</a> implementiert. Eine Validation Rule um zu prüfen, ob in unserem Beispiel die eingegebene Jahreszahl innerhalb des gewünschten Zeitraums ist, könnte so aussehen:</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:a81134c5-2191-4f20-a3a3-3341db8863b7" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">public class NumberInRangeValidationRule : ValidationRule
{
    public int MaxValue { get; set; }
    public int MinValue { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        Debug.WriteLine("entering NumberInRangeValidationRule.Validate");

        // InvalidCast Exception is wanted if this rule is used the wrong way.
        int intValue = (int)value;

        if( intValue &lt; MinValue || intValue &gt; MaxValue )
        {
            return new ValidationResult(false,
                                        string.Format("Please enter a number between {0} and {1}.",
                                                      MinValue, MaxValue));
        }

        return ValidationResult.ValidResult;
    }
}</pre>
</div>
<p>Diese Validation Rule bietet die Möglichkeit über zwei Eigenschaften den gewünschten Wertebereich anzugeben. In der Validate Methode wird dann überprüft, ob der eingegebene Wert innerhalb dieses Bereichs ist. Ist das nicht der Fall, wird ein ValidationResult mit einem entsprechenden Text zurückgegeben. Warum aber der Test, ob der übergebene Wert vom Typ int ist (Zeile 10)? Schauen wir uns mal an, wie diese Rule im XAML verwendet wird:</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:81dafe47-c586-48ab-8524-c0f5e1472a75" class="wlWriterSmartContent">
<pre class="xml:nogutter:nocontrols" name="code">...
&lt;TextBox.Text&gt;
    &lt;Binding Source=&quot;{StaticResource cd}&quot;
             Path=&quot;Year&quot;
             UpdateSourceTrigger=&quot;PropertyChanged&quot;
             ValidatesOnExceptions=&quot;True&quot;&gt;
        &lt;Binding.ValidationRules&gt;
            &lt;local:NumberInRangeValidationRule MinValue=&quot;1980&quot;
                                               MaxValue=&quot;2009&quot;
                                               ValidationStep=&quot;ConvertedProposedValue&quot;/&gt;
        &lt;/Binding.ValidationRules&gt;
    &lt;/Binding&gt;
&lt;/TextBox.Text&gt;
...</pre>
</div>
<p>Ab .Net 3.5 SP1 gibt es die Eigenschaft <a href="http://msdn.microsoft.com/de-de/library/system.windows.controls.validationrule.validationstep.aspx">ValidationStep</a> an der Klasse ValidationRule. Darüber kann man angeben, zu welchem Zeitpunkt während des Databindingvorganges die Validierung erfolgen soll. Es stehen vier Möglichkeiten zur Auswahl:</p>
<ol>
<li>RawProposedValue – Das ist der Defaultwert. Die Validierung wird vorgenommen bevor der Wert konvertiert wird. In dem Beispiel mit der TextBox muss damit ein String validiert werden (die Text Eigenschaft ist vom Typ String). </li>
<li>ConvertedProposedValue – Bei dieser Einstellung wird der konvertierte Wert validiert. Im Beispiel also ein Integer. </li>
<li>UpdatedValue – Die Validierung erfolgt nachdem die Quelle aktualisiert wurde. </li>
<li>CommittedValue &#8211; Die Validierung erfolgt nachdem der Wert an die Quelle übergeben wurde.</li>
</ol>
<p>Die letzten beiden Optionen sind mir ein bisschen suspekt. Mir ist kein Anwendungsfall eingefallen und der Unterschied zwischen beiden ist mir auch nicht klar.</p>
<ol>Die oben gezeigte NumberInRangeValidationRule arbeitet auf Integer Werten, weshalb ich “ConvertedProposedValue” als ValidationStep angegeben habe. Bei der Implementierung ist eine InvalidCastException gewollt, damit eine falsche Benutzung sofort bemerkt wird.</ol>
<ol>So, jetzt fehlt nur noch ein schönerer Text für den Fall, dass keine Zahl sondern irgendwas anderes eingegeben wird. Dazu schreiben wir noch eine IsValidIntegerValidationRule: </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:68e9c3e3-5cde-44dc-84da-70f9c2ce2fbf" class="wlWriterEditableSmartContent">
<pre name="code" class="c#:nogutter:nocontrols">public class IsValidIntegerValidationRule : ValidationRule
{
    public override ValidationResult Validate( object value, System.Globalization.CultureInfo cultureInfo )
    {
        Debug.WriteLine( "entering IsValidIntegerValidationRule.Validate" );
        string inputString = value as string;

        if (null != inputString)
        {
            int inputNumber;
            if( false == int.TryParse(inputString, out inputNumber ) )
            {
                return new ValidationResult( false, "Please enter a valid number." );
            }
        }

        return ValidationResult.ValidResult;
    }
}</pre>
</div>
<p>Für diese Validation Rule belassen wir den ValidationStep beim Default, also “RawProposedValue”. Damit sieht die finale Konfiguration für das Databinding so aus:</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:ee27539d-8dbe-4376-987c-6fae0644b142" class="wlWriterSmartContent">
<pre class="xml:nogutter:nocontrols" name="code">...
&lt;TextBox ToolTip=&quot;Please enter year of release&quot;
         Width=&quot;60&quot;
         Margin=&quot;10&quot;
         Validation.ErrorTemplate=&quot;{StaticResource TextBoxErrorTemplate}&quot;&gt;
    &lt;TextBox.Text&gt;
        &lt;Binding Source=&quot;{StaticResource cd}&quot;
                 Path=&quot;Year&quot;
                 UpdateSourceTrigger=&quot;PropertyChanged&quot;&gt;
            &lt;Binding.ValidationRules&gt;
                &lt;local:NumberInRangeValidationRule MinValue=&quot;1980&quot;
                                                   MaxValue=&quot;2009&quot;
                                                   ValidationStep=&quot;ConvertedProposedValue&quot;/&gt;
                &lt;local:InputMustBeIntegerValidationRule ValidationStep=&quot;RawProposedValue&quot;/&gt;

            &lt;/Binding.ValidationRules&gt;
        &lt;/Binding&gt;
    &lt;/TextBox.Text&gt;
&lt;/TextBox&gt;
...</pre>
</p></div>
<p>Uns so sieht das Ganze dann im UI aus:</ol>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Invalid input format" border="0" alt="Invalid input format" src="http://berndhengelein.de/wp-content/uploads/2009/03/image3.png" width="404" height="134" /> </p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Input out of range" border="0" alt="Input out of range" src="http://berndhengelein.de/wp-content/uploads/2009/03/image4.png" width="404" height="134" /> </p>
<ol>Jetzt gibt es noch ein Problem, für das ich bisher noch keine zufriedenstellende Lösung gefunden habe. Beim Start der Anwendung wird über das TwoWay Binding der Initiale Wert aus der Quelle geholt. Dieser Wert ist bei einem Integer 0. Der Wert 0 liegt nicht im Wertebereich der NumberInRangeValidationRule, es wird aber keine Validierungsmeldung angezeigt. Es sieht so aus, also ob die Validierung nur von Ziel zu Quelle durchgeführt wird. Hier bin ich für Ideen bzw. Lösungsvorschläge sehr dankbar.</ol>
<p>Der nächste Post zum Thema Validierung mit WPF widmet sich dem IDataErrorInfo Interface. Die Unterstützung dafür wurde mit .Net 3.5 SP1 in WPF eingeführt. Ich bin gespannt.</p>
</p>
</p>
<p>Das komplette Beispiel kann hier heruntergeladen werden:</p>
<p><iframe style="border-bottom: #dde5e9 1px solid; border-left: #dde5e9 1px solid; padding-bottom: 0px; background-color: #ffffff; margin: 3px; padding-left: 0px; width: 94px; padding-right: 0px; height: 94px; border-top: #dde5e9 1px solid; border-right: #dde5e9 1px solid; padding-top: 0px" marginheight="0" src="http://cid-a575d63718548aa9.skydrive.live.com/embedgrid.aspx/Public/Examples%20from%20blog/DataValidationWPF%7C_ValidationRules.zip" frameborder="0" marginwidth="0" scrolling="no"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/03/databinding-und-validierung-in-wpf-%e2%80%93-validation-rules/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WPF Databinding in Verbindung mit einem Defaultbutton</title>
		<link>http://berndhengelein.de/2009/03/wpf-databinding-in-verbindung-mit-einem-defaultbutton/</link>
		<comments>http://berndhengelein.de/2009/03/wpf-databinding-in-verbindung-mit-einem-defaultbutton/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 20:53:00 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=152</guid>
		<description><![CDATA[Vor kurzem ist ein Kollege von mir auf ein kleines Problem mit Databinding gestoßen. Und zwar in Verbindung mit einem Button dessen “IsDefault” Eigenschaft auf True gesetzt ist. Es wurde die Bindingquelle nicht aktualisiert.
Zur Verdeutlichung soll folgendes UI dienen:

Die TextBox für den Username ist über Databinding an die “Username” Eigenschaft des ViewModels angebunden. Bei dem [...]]]></description>
			<content:encoded><![CDATA[<p>Vor kurzem ist ein Kollege von mir auf ein kleines Problem mit Databinding gestoßen. Und zwar in Verbindung mit einem Button dessen “IsDefault” Eigenschaft auf True gesetzt ist. Es wurde die Bindingquelle nicht aktualisiert.</p>
<p>Zur Verdeutlichung soll folgendes UI dienen:</p>
<p><a href="http://berndhengelein.de/wp-content/uploads/2009/03/image.png"><img title="Defaultbutton with databinding" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="164" alt="Defaultbutton with databinding" src="http://berndhengelein.de/wp-content/uploads/2009/03/image-thumb.png" width="304" border="0" /></a></p>
<p>Die TextBox für den Username ist über Databinding an die “Username” Eigenschaft des ViewModels angebunden. Bei dem Ok Button ist “IsDefault” auf True gesetzt. Mit Hilfe einiger Traces kann man im Ausgabefenster des Visual Studio sehen, was vom Benutzer eingegeben wurde.</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5a4da999-5f76-4aa0-aec4-968593782644" 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 string Username
{
    get { return _userName; }
    set
    {
        _userName = value;
        Trace.WriteLine(string.Format("Username {0} entered.", _userName));
    }
}
...
private void OnOkCommand()
{
    Trace.WriteLine("Ok button pressed.");
    Trace.WriteLine(string.Format("Current username {0}", _userName));

}
...</pre>
</div>
<div>Wenn nach der Eingabe eines Benutzernamens der Ok Button mit der Maus geklickt wird, klappt alles wie erwartet. Der Setter der Username Eigenschaft wird aufgerufen und dannach die Methode OnOkCommand() ausgeführt. Wird allerdings direkt nach der Eingabe die Enter Taste gedrückt, wird zwar OnOkCommand() ausgeführt, aber nicht der Username Setter. Was ist hier los?</div>
<p>Bei einer TextBox die per Databinding angebunden ist, wird die Quelle per Default bei Verlust des Fokus aktualisiert. D.h. die Eigenschaft “UpdateSourceTrigger” des Bindings hat den Wert “LostFocus”. Scheinbar wird beim Auslösen eines Defaultbuttons der Fokus nicht auf diesen Button gesetzt. Es wird dann zwar das Command ausgeführt welches mit dem Button verknüpft ist, aber die Quelle der TextBox wurde nicht aktualisiert.</p>
<p>Es gibt mehrere Möglichkeiten das Problem zu lösen.</p>
<ol>
<li>Durch Setzen der “UpdateSourceTrigger” Eigenschaft am Binding auf “PropertyChanged”. Dadurch wird die Quelle bei jeder Veränderung aktualisiert. </li>
<li>Durch manuelles Setzen des Fokus im Click-Eventhandler des Buttons </li>
<li>Durch manuelles Aktualisieren des Bindings im Click-Eventhandler des Buttons </li>
</ol>
<p>Bei Variante zwei muss der entsprechende Code in die Code-Behind Datei der View verlagert werden, da ein direkter Zugriff auf das Button Control notwendig ist:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:076bbdd2-abe9-46cc-b485-4bf639559ead" 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">private void OnOkButtonClick(object sender, RoutedEventArgs e)
{
    FocusManager.SetFocusedElement(this, (Button)sender);
}</pre>
</div>
<p>Den Code für die dritte Lösung könnte man (technisch) auch ins ViewModel packen. Gefällt mir aber nicht, da ich im ViewModel keine Kenntnis von UI Controls haben möchte. Deshalb kommt auch hier die Code-Behind Datei zu Zuge:</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:40f6d627-1aff-4184-9090-463115f09683" 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">private void OnOkButtonClick(object sender, RoutedEventArgs e)
{
    TextBox focusedTextBox = Keyboard.FocusedElement as TextBox;
    if( null != focusedTextBox )
    {
        BindingExpression bindingExpression = focusedTextBox.GetBindingExpression(TextBox.TextProperty);
        if (null != bindingExpression)
        {
            bindingExpression.UpdateSource();
        }
    }
}</pre>
</div>
<p>Bisher gefällt mir die zweite Variante am Besten. Mir sind auch noch keine Nachteile oder Probleme aufgefallen. Den “richtigen” Code, der beim Auslösen des Defaultbuttons ausgeführt werden soll, kann man im ViewModel lassen. Das Command welches mit dem Button verknüpft ist, wird erst nach dem Click Event ausgeführt.</p>
<p>Weiss zufällig jemand, ob es diesen Effekt mit dem Defaultbutton und LostFocus auch unter WinForms gibt?</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/03/wpf-databinding-in-verbindung-mit-einem-defaultbutton/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tools f&#252;r WPF und Silverlight Entwickler</title>
		<link>http://berndhengelein.de/2009/02/tools-fr-wpf-und-silverlight-entwickler/</link>
		<comments>http://berndhengelein.de/2009/02/tools-fr-wpf-und-silverlight-entwickler/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 18:18:58 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=119</guid>
		<description><![CDATA[Ich sehe schon die Gedanken in euren Köpfen : “Oh je, schon wieder einer der ‘ne Toolliste postet”, “Nicht schon wieder. Scott Hanselman macht das doch schon seit Jahren”. Ihr habt ja recht – trotzdem tue ich es, in der Hoffnung Ergänzungsvorschläge zu bekommen.

KAXAML – Ein super XAML Editor, mit dem mal schnell mal was [...]]]></description>
			<content:encoded><![CDATA[<p>Ich sehe schon die Gedanken in euren Köpfen : “Oh je, schon wieder einer der ‘ne Toolliste postet”, “Nicht schon wieder. <a href="http://www.hanselman.com/blog/ScottHanselmans2007UltimateDeveloperAndPowerUsersToolListForWindows.aspx">Scott Hanselman</a> macht das doch schon seit Jahren”. Ihr habt ja recht – trotzdem tue ich es, in der Hoffnung Ergänzungsvorschläge zu bekommen.</p>
<ul>
<li><a href="http://www.kaxaml.com/" target="_blank">KAXAML</a> – Ein super XAML Editor, mit dem mal schnell mal was ausprobieren kann ohne gleich das Visual Studio zu starten. Er bietet ein geteiltes Fenster, so dass der XAML Code und das gerenderte Ergebnis auf einem Blick zu sehen sind. Syntax-Highlighting und Codevervollständigung gehören auch zum Funktionsumfang. In der aktuellen Beta Version wird auch Silverlight 2 unterstützt.</li>
<li><a href="http://blois.us/Snoop/" target="_blank">Snoop</a> – Snoop könnte man als “Visual Debugger” bezeichnen. Das Tool kann sich zur Laufzeit an eine WPF Anwendung “attachen” und zeigt dann den Visual Tree derselben an. Dort lassen sich z.B. Properties verändern und Routed Events verfolgen. Wie man Databindingprobleme mit Snoop findet, habe ich <a href="../2009/01/wpf-databinding-probleme-mit-snoop-finden/" target="_blank">hier</a> beschrieben.</li>
<li><a href="http://www.sellsbrothers.com/tools/#ShowMeTheTemplate" target="_blank">ShowMeTheTemplate</a> – Zeigt die Templates (ControlTemplate, DataTemplate und ItemsPanelTemplate) für alle mit WPF ausgelieferten Controls an. Auf MSDN gibt es auch Beispiele für ControlTemplates: “<a href="http://msdn.microsoft.com/en-us/library/aa970773(VS.85).aspx" target="_blank">Control Template Examples</a>”.</li>
<li><a href="http://joshsmithonwpf.wordpress.com/cracknet/" target="_blank">Crack.Net</a> – Crack.Net ist zwar kein Tool das speziell <em>für</em> WPF entwickelt wurde, es wurde aber <em>mit</em> WPF entwickelt. Ähnlich wie Snoop “attached” sich Crack.Net an eine laufende .Net Anwendung. Es ist möglich, den managed Heap der Applikation zu untersuchen, Objekte können direkt verändert werden und mit IronPython ist sogar Scripting Support vorhanden. Der Entwickler Josh Smith hat hier konsequent das <a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx" target="_blank">M-V-VM Pattern</a> verwendet. Ein Blick auf den <a href="http://www.codeplex.com/cracknetproject" target="_blank">Sourcecode</a> kann hier nicht schaden.</li>
<li><a href="http://msdn.microsoft.com/en-us/library/aa969767.aspx" target="_blank">Performance Profiling Tools for WPF</a> – Sammlung von fünf Tools von Microsoft, die helfen sollen Performanceprobleme bei WPF Anwendungen zu finden bzw. zu vermeiden. Mit dem enthaltenen Visual Profiler lässt sich auch mal schnell ein Performancevergleich zwischen zwei Rechnern machen.</li>
<li><a href="http://karlshifflett.wordpress.com/mole-for-visual-studio/" target="_blank">Mole</a> – Ein Visualizer für Visual Studio mit dem während des Debuggens nicht nur sämtliche Eigenschaften eines Objekts editiert werden können, sondern bei WPF Anwendungen auch der Logical/Visual Tree betrachtet werden kann.</li>
<li><a href="http://www.drwpf.com/Blog/Default.aspx?tabid=36&amp;EntryID=22" target="_blank">Dr. WPF’s Code Snippets</a> – sind zwar kein Tool, aber auch sehr hilfreich. Momentan sind Snippets für Dependency Properties, Routed Commands und Routed Events enthalten. Wer selber Code Snippets schreibt, findet mit dem <a href="http://www.codeplex.com/SnippetEditor" target="_blank">Snippet Editor</a> einen Helfer.</li>
<li><a href="http://www.microsoft.com/expression/products/Overview.aspx?key=blend" target="_blank">Microsoft Expression Blend</a> – Das Design Tool für WPF und Silverlight (mit SP1 für Expression Blend). Bisher habe ich es nur rudimentär verwendet. Ich glaube aber, dass es auch für Entwickler sehr hilfreich ist, dieses Tool zumindest in den Grundzügen zu beherrschen.</li>
</ul>
<p>Tools können sehr hilfreich sein, sind aber natürlich kein Allheilmittel! Bei vielen Problemen kann es auch helfen, einfach einen Kollegen über den Code schauen zu lassen.</p>
<p>Welche Tools verwendet ihr bei der WPF Entwicklung?</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/02/tools-fr-wpf-und-silverlight-entwickler/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The type reference cannot find a public type named &#8216;InsertYourType&#8217;</title>
		<link>http://berndhengelein.de/2009/01/the-type-reference-cannot-find-a-public-type-named-insertyourtype/</link>
		<comments>http://berndhengelein.de/2009/01/the-type-reference-cannot-find-a-public-type-named-insertyourtype/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 19:05:56 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=93</guid>
		<description><![CDATA[Heute hatte ich eine interessante Diskussion mit Norbert auf .NET GUI. Unter anderem habe ich gelernt, dass es Probleme geben kann, wenn beim Import eines lokalen Namespace in ein XAML File der Assemblyname mit angegeben wird. Hier ein Beispiel: 
In der Assembly DataTemplateDemo gibt es eine Klasse Data:

namespace DatatemplateDemo
{
    public class Data
 [...]]]></description>
			<content:encoded><![CDATA[<p>Heute hatte ich eine interessante <a href="http://dotnet-gui.com/forums/t/404.aspx">Diskussion</a> mit <a href="http://blog.norberteder.com/">Norbert</a> auf <a href="http://dotnet-gui.com/">.NET GUI</a>. Unter anderem habe ich gelernt, dass es Probleme geben kann, wenn beim Import eines lokalen Namespace in ein XAML File der Assemblyname mit angegeben wird. Hier ein Beispiel: </p>
<p>In der Assembly DataTemplateDemo gibt es eine Klasse Data:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">namespace</span> DatatemplateDemo
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Data
    {
        <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> _name;

        <span style="color: #0000ff">public</span> Data(<span style="color: #0000ff">string</span> name)
        {
            _name = name;
        }

        <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Name
        {
            get { <span style="color: #0000ff">return</span> _name; }
        }
    }
}</pre>
</div>
<p>Im UI wird ein DataTemplate für diesen Typ definiert:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Window</span> <span style="color: #ff0000">x:Class</span><span style="color: #0000ff">=&quot;DatatemplateDemo.Window1&quot;</span>
    <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span style="color: #ff0000">xmlns:x</span><span style="color: #0000ff">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span style="color: #ff0000">xmlns:local</span><span style="color: #0000ff">=&quot;clr-namespace:DatatemplateDemo;assembly=DatatemplateDemo&quot;</span>
    <span style="color: #ff0000">Title</span><span style="color: #0000ff">=&quot;Window1&quot;</span> <span style="color: #ff0000">Height</span><span style="color: #0000ff">=&quot;300&quot;</span> <span style="color: #ff0000">Width</span><span style="color: #0000ff">=&quot;300&quot;</span><span style="color: #0000ff">&gt;</span>

    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">DataTemplate</span> <span style="color: #ff0000">x:Key</span><span style="color: #0000ff">=&quot;DataTemplate_Data&quot;</span> <span style="color: #ff0000">DataType</span><span style="color: #0000ff">=&quot;{x:Type local:Data}&quot;</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">StackPanel</span> <span style="color: #ff0000">Orientation</span><span style="color: #0000ff">=&quot;Horizontal&quot;</span><span style="color: #0000ff">&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBlock</span> <span style="color: #ff0000">Margin</span><span style="color: #0000ff">=&quot;2&quot;</span> <span style="color: #ff0000">Text</span><span style="color: #0000ff">=&quot;Name: &quot;</span><span style="color: #0000ff">/&gt;</span>
                <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBlock</span> <span style="color: #ff0000">Margin</span><span style="color: #0000ff">=&quot;2&quot;</span> <span style="color: #ff0000">Text</span><span style="color: #0000ff">=&quot;{Binding Path=Name}&quot;</span><span style="color: #0000ff">/&gt;</span>
            <span style="color: #0000ff">&lt;/</span><span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">DataTemplate</span><span style="color: #0000ff">&gt;</span>

    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span>

    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">ListBox</span> <span style="color: #ff0000">x:Name</span><span style="color: #0000ff">=&quot;_listBox&quot;</span> <span style="color: #ff0000">ItemTemplate</span><span style="color: #0000ff">=&quot;{StaticResource DataTemplate_Data}&quot;</span><span style="color: #0000ff">/&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Grid</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Wenn man nun versucht diesen Code zu übersetzen wird man mit dieser Fehlermeldung konfrontiert: </p>
<blockquote>
<p>error MC3066: The type reference cannot find a public type named &#8216;Data&#8217;. Line 8 Position 80.</p>
</blockquote>
<p>Nach einigem Rumprobieren hat sich herausgestellt, dass die Übersetzung wunderbar klappt, wenn bei der Deklaration des XML Namespace die Assembly weggelassen wird:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Window</span> <span style="color: #ff0000">x:Class</span><span style="color: #0000ff">=&quot;DatatemplateDemo.Window1&quot;</span>
    <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span style="color: #ff0000">xmlns:x</span><span style="color: #0000ff">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span style="color: #ff0000">xmlns:local</span><span style="color: #0000ff">=&quot;clr-namespace:DatatemplateDemo&quot;</span>
    <span style="color: #ff0000">Title</span><span style="color: #0000ff">=&quot;Window1&quot;</span> <span style="color: #ff0000">Height</span><span style="color: #0000ff">=&quot;300&quot;</span> <span style="color: #ff0000">Width</span><span style="color: #0000ff">=&quot;300&quot;</span><span style="color: #0000ff">&gt;</span>

    ...

<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Der Fehler tritt nicht nur mit DataTemplates auf, sondern z.B. auch wenn man einen Style definiert und der TargetType entsprechend angegeben wird. </p>
<p>Ich merke mir: wenn ein Namespace aus einem lokalen Assembly in ein XAML File mit xmlns importiert wird, gebe ich den “assembly” Parameter NICHT mit an! Vielleicht erspart die Info ja dem einen oder anderen die Fehlersuche. Ach ja, das Intellisense des Visual Studio macht es automatisch so und gibt den “assembly” Parameter nicht mit an, wenn der importierte CLR Namespace im gleichen Assembly liegt. </p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/01/the-type-reference-cannot-find-a-public-type-named-insertyourtype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Artikel &#252;ber M-V-VM im MSDN Magazin</title>
		<link>http://berndhengelein.de/2009/01/artikel-ber-m-v-vm-im-msdn-magazin/</link>
		<comments>http://berndhengelein.de/2009/01/artikel-ber-m-v-vm-im-msdn-magazin/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 08:18:20 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Neuigkeiten]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=79</guid>
		<description><![CDATA[Josh Smith hat für die Februar Ausgabe des englischen MSDN Magazins einen Artikel über das M-V-VM (Model-View-ViewModel) Pattern geschrieben. Dieses, mittlerweile sehr populäre, UI Pattern für WPF wurde von John Gossman geprägt und findet auch in der Architektur von Expression Blend Anwendung. M-V-VM bietet Richtlinien, einen Leitfaden um testbare WPF Anwendungen mit einer sauberen Trennung [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://joshsmithonwpf.wordpress.com/">Josh Smith</a> hat für die Februar Ausgabe des englischen MSDN Magazins einen <a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx">Artikel</a> über das <a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx">M-V-VM</a> (Model-View-ViewModel) Pattern geschrieben. Dieses, mittlerweile sehr populäre, UI Pattern für WPF wurde von <a href="http://blogs.msdn.com/johngossman/default.aspx">John Gossman</a> geprägt und findet auch in der Architektur von <a href="http://www.microsoft.com/expression/products/Overview.aspx?key=blend">Expression Blend</a> Anwendung. M-V-VM bietet Richtlinien, einen Leitfaden um testbare WPF Anwendungen mit einer sauberen Trennung von Daten, Businesslogik und UI zu entwickeln.</p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/01/artikel-ber-m-v-vm-im-msdn-magazin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Databinding und Validierung in WPF &#8211; erste Vorbereitungen</title>
		<link>http://berndhengelein.de/2009/01/databinding-und-validierung-in-wpf-erste-vorbereitungen/</link>
		<comments>http://berndhengelein.de/2009/01/databinding-und-validierung-in-wpf-erste-vorbereitungen/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 12:15:02 +0000</pubDate>
		<dc:creator>Bernd</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://berndhengelein.de/?p=74</guid>
		<description><![CDATA[Databinding in WPF ist ein sehr weites Feld. Nicht zuletzt aufgrund der Vielseitigkeit und Mächtigkeit spielt Databinding in WPF eine sehr wichtige Rolle. Einige wichtige Merkmale sind: 

Bindings können sowohl in XAML als auch im Code erzeugt werden. 
Konvertierung von Daten. Über sog. Value Converter ist es möglich, die Daten die von der Quelle kommen [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/library/ms752347.aspx">Databinding</a> in WPF ist ein sehr weites Feld. Nicht zuletzt aufgrund der Vielseitigkeit und Mächtigkeit spielt Databinding in WPF eine sehr wichtige Rolle. Einige wichtige Merkmale sind: </p>
<ul>
<li>Bindings können sowohl in XAML als auch im Code erzeugt werden. </li>
<li>Konvertierung von Daten. Über sog. <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx">Value Converter</a> ist es möglich, die Daten die von der Quelle kommen anzupassen bzw. zu verändern. </li>
<li><a href="http://msdn.microsoft.com/en-us/library/system.windows.datatemplate.aspx">Data Templates</a> &#8211; mit Data Templates kann man die Visualisierung der Daten festlegen. </li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms752347.aspx#data_validation">Data Validation</a> – wie unterstützt mich WPF bei der Validierung der vom Benutzer eingegebenen Daten? </li>
</ul>
<p>Um Data Validation soll es in den nächsten Posts gehen. Ich kann leider keine Weisheiten zu dem Thema bieten, sondern möchte vielmehr meinen Lernprozess (mit)teilen. In mehreren Postings nähere ich mich Schritt für Schritt dem Thema. Danach wissen wir hoffentlich alle ein bisschen mehr über Databinding und Data Validation mit WPF. </p>
<p>Um erst mal die Grundlagen zu verstehen, fange ich ganz klein an. So klein, dass es mir schon fast zu klein vorkommt… aber nur fast. So sieht das Fenster der Testanwendung aus: </p>
<p><img src="http://berndhengelein.de/wp-content/uploads/2009/02/datavalidation01.png" /> </p>
</p>
<p>Das zugehörige XAML ist auch ganz einfach:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Window</span> <span style="color: #ff0000">x:Class</span><span style="color: #0000ff">=&quot;DataValidationWPF.Window1&quot;</span>
    <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span>
    <span style="color: #ff0000">xmlns:x</span><span style="color: #0000ff">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span>
    <span style="color: #ff0000">xmlns:local</span><span style="color: #0000ff">=&quot;clr-namespace:DataValidationWPF&quot;</span>
    <span style="color: #ff0000">Title</span><span style="color: #0000ff">=&quot;Data validation with WPF&quot;</span>
    <span style="color: #ff0000">Height</span><span style="color: #0000ff">=&quot;130&quot;</span> <span style="color: #ff0000">Width</span><span style="color: #0000ff">=&quot;300&quot;</span><span style="color: #0000ff">&gt;</span>

    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">local:CompactDisc</span> <span style="color: #ff0000">x:Key</span><span style="color: #0000ff">=&quot;cd&quot;</span> <span style="color: #0000ff">/&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window.Resources</span><span style="color: #0000ff">&gt;</span>

    <span style="color: #0000ff">&lt;</span><span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBlock</span> <span style="color: #ff0000">Text</span><span style="color: #0000ff">=&quot;Please enter a value between 1980 and 2009&quot;</span>
                   <span style="color: #ff0000">Margin</span><span style="color: #0000ff">=&quot;10&quot;</span><span style="color: #0000ff">/&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">StackPanel</span> <span style="color: #ff0000">Orientation</span><span style="color: #0000ff">=&quot;Horizontal&quot;</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBlock</span> <span style="color: #ff0000">Text</span><span style="color: #0000ff">=&quot;Year:&quot;</span> <span style="color: #ff0000">Margin</span><span style="color: #0000ff">=&quot;10&quot;</span> <span style="color: #0000ff">/&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">TextBox</span> <span style="color: #ff0000">ToolTip</span><span style="color: #0000ff">=&quot;Please enter year of release&quot;</span>
                     <span style="color: #ff0000">Width</span><span style="color: #0000ff">=&quot;60&quot;</span>
                     <span style="color: #ff0000">Margin</span><span style="color: #0000ff">=&quot;10&quot;</span>
                     <span style="color: #ff0000">Text</span><span style="color: #0000ff">=&quot;{Binding Source={StaticResource cd},
                            Path=Year,
                            Mode=TwoWay,
                            UpdateSourceTrigger=PropertyChanged}&quot;</span><span style="color: #0000ff">/&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">StackPanel</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Window</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>Als Datenklasse muss wieder die CompactDisc herhalten. Diesmal total abgespeckt in ihrer Minimalausführung:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> CompactDisc
{
    <span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> _year;

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> Year
    {
        get
        {
            Debug.WriteLine(<span style="color: #006080">&quot;Get year: &quot;</span> + _year);
            <span style="color: #0000ff">return</span> _year;
        }

        set
        {
            _year = <span style="color: #0000ff">value</span>;
            Debug.WriteLine(<span style="color: #006080">&quot;Set year to: &quot;</span> + _year);
        }
    }
}</pre>
</div>
<p>Es wird also die “Year” Eigenschaft einer Instanz der CompactDisc Klasse an die “Text” Eigenschaft einer TextBox im UI gebunden. Als Mode für die Bindung habe ich “TwoWay” angegeben. D.h. der Datenaustauch erfolgt in beide Richtungen. Nach dem Starten der Applikation wird direkt der Wert ‘0’ in der TextBox angezeigt. 0 ist der <a href="http://msdn.microsoft.com/en-us/library/83fhsxwc.aspx">Default Wert</a> für den Typ int. Das TwoWay Binding funktioniert also. Selbst bei diesem einfachen Beispiel passiert schon einiges unter der Databinding Haube. Damit überhaupt ein Integer Wert in einer TextBox angezeigt werden kann, durchläuft dieser eine implizite Konvertierung zu einem String. </p>
<p>Zu Diagnosezwecken wurden im Setter und Getter der Eigenschaft jeweils eine Debugausgabe eingebaut. Damit kann man dann im Output Fenster des Visual Studios sehen, ob überhaupt etwas geändert wurde. Um auch wirklich alle Änderungen, die im UI in der TextBox gemacht werden mitzubekommen, habe ich die Eigenschaft “<a href="http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx">UpdateSourceTrigger</a>” auf den Wert “PropertyChanged” gesetzt. Das bewirkt, dass die Quelle des Bindings (die Year Eigenschaft) aktualisiert wird, sobald in der TextBox editiert wird. Los geht’s. Applikation im Debug Modus aus dem Visual Studio starten und die Debug Ausgaben im Auge behalten. </p>
<p>Sobald die ‘0’ aus der TextBox gelöscht wird, taucht auch schon die erste Fehlermeldung im Output Fenster auf: </p>
<blockquote>
<p>A first chance exception of type &#8216;System.FormatException&#8217; occurred in mscorlib.dll<br />
    <br />A first chance exception of type &#8216;System.Reflection.TargetInvocationException&#8217; occurred in mscorlib.dll </p>
<p>A first chance exception of type &#8216;System.FormatException&#8217; occurred in mscorlib.dll </p>
<p>System.Windows.Data Error: 7 : ConvertBack cannot convert value &#8221; (type &#8216;String&#8217;). BindingExpression:Path=Year; DataItem=&#8217;CompactDisc&#8217; (HashCode=59835590); target element is &#8216;TextBox&#8217; (Name=&#8221;); target property is &#8216;Text&#8217; (type &#8216;String&#8217;) FormatException:&#8217;System.FormatException: Input string was not in a correct format. </p>
<p>&#160;&#160; at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer&amp; number, NumberFormatInfo info, Boolean parseDecimal) </p>
<p>&#160;&#160; at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) </p>
<p>&#160;&#160; at System.String.System.IConvertible.ToInt32(IFormatProvider provider) </p>
<p>&#160;&#160; at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) </p>
<p>&#160;&#160; at MS.Internal.Data.SystemConvertConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture) </p>
<p>&#160;&#160; at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)&#8217; </p>
<p>The thread 0xf44 has exited with code 0 (0&#215;0).</p>
</blockquote>
<p>&#160;</p>
<p>Bei der impliziten Konvertierung gibt es eine FormatException. Die Anwendung läuft trotzdem ohne Probleme weiter. Offensichtlich wird die Exception vom Databinding System geschluckt. Man sieht auch, dass der Setter der Year Eigenschaft nicht aufgerufen wird. Bisher bekommen wir also in unserem Code nichts mit und haben dadurch auch nicht die Möglichkeit dem Benutzer einen entsprechenden Hinweis zu geben (z.B. eine Meldung “Year must not be empty”). Aber hier soll uns ja Data Validation weiterhelfen. Wird eine gültige Zahl in die TextBox eingegeben läuft alles nach Plan, der Setter wird aufgerufen und das Datenobjekt ist auf Stand. </p>
<p>So, das war&#8217;s für den ersten Teil. Man sieht, dass selbst bei so einfachen Anwendungen mit Databinding eine Menge passiert. Ich bin gespannt, was WPF bzgl. Validierung für uns Entwickler bereithält. </p>
]]></content:encoded>
			<wfw:commentRss>http://berndhengelein.de/2009/01/databinding-und-validierung-in-wpf-erste-vorbereitungen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

