<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://community.dotned.nl/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Dennis' avonturen in .net</title><link>http://community.dotned.nl/blogs/dennis_blog/default.aspx</link><description>Een blog over van alles, zolang het maar met Microsoft .net te maken heeft. Nou ja, er is ook een categorie genaamd "From The Trenches", waarin ik vertel over de vreemde dingen die ik meemaak in mijn vakgebied. De meeste van die verhalen zijn absoluut niet technisch maar ik denk dat velen van jullie de strekking van de verhalen wel herkennen.</description><dc:language>nl-NL</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Isolated Storage en OpenFileDialog in Silverlight</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/08/27/1071.aspx</link><pubDate>Fri, 27 Aug 2010 08:32:22 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1071</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1071.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1071</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1071.aspx</wfw:comment><description>&lt;p&gt;In een project waar ik aan werk hebben we de mogelijkheid om plaatjes te uploaden naar een server. Niet echt wereldschokkend, we hebben dit immers vaak genoeg gezien. &lt;/p&gt;  &lt;p&gt;Het scenario is dit: een klant kan een verzoek doen tot een onderzoek, en om de onderzoeker te helpen kan hij foto’s van het te onderzoeken object meesturen. De flow is ongeveer dit:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/6d876efc7aba_87E7/image.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/6d876efc7aba_87E7/image_thumb.png" width="856" height="117" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In stap twee krijgt de gebruiker de mogelijkheid om een aantal foto’s te selecteren die met de aanvraag meegestuurd moeten worden. Pas na het bevestigen in stap 4 wordt de gehele aanvraag verstuurd naar de server.&lt;/p&gt;  &lt;p&gt;Simpel. &lt;/p&gt;  &lt;p&gt;In stap 2 moet ik de gebruiker dus een OpenFileDialog presenteren en de geselecteerde bestanden opslaan tot we de foto’s kunnen uploaden. In mijn ViewModel sla ik dus het pad naar de bestanden op, zodat ik die later kan versturen. Tenminste, dat was het plan. Zie onderstaande code snippet:&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;OpenFileDialog&lt;/span&gt; ofd = &lt;span class="cb2"&gt;new&lt;/span&gt; &lt;span class="cb1"&gt;OpenFileDialog&lt;/span&gt;();&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;if&lt;/span&gt; (ofd.ShowDialog().GetValueOrDefault() == &lt;span class="cb2"&gt;true&lt;/span&gt;)&lt;/p&gt;    &lt;p class="cl"&gt;{&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;string&lt;/span&gt; fullName = ofd.File.FullName;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;// Store in the viewmodel&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;tja.. Niet dus. Als je dit runt krijg je een exception met de mooie tekst “File Operation not permitted. Access to path ‘’ is denied.” Je kunt wel de filename opvragen, maar niet het pad. En op dat moment maakte ik een domme fout. Ik dacht: “Ok, als ik dit niet kan doen, dan ga ik het bestand wel even kopieren naar de IsolatedStorage zodat ik ze later kan versturen.” Op zich niet verkeerd: de bestanden worden gekopieerd en pas verstuurd als de gebruiker dit bevestigd heeft. Daarna kan ik de bestanden verwijderen uit de IsolatedStorage en zoals ze zeggen “All is well…”. Voor diegene die niet weten wat de IsolatedStorage is: het is een container waar alleen jouw applicatie bij kan en die vertrouwd wordt door Silverlight. Dat is dus de plek waar je bestanden kunt wegschrijven. In principe heb je immers geen rechten om bestanden weg te schrijven in het filesystem: dit zou een enorm security probleem kunnen veroorzaken.&lt;/p&gt;  &lt;p&gt;Nu is de ruimte die je hebt in de IsolatedStorage standaard niet al te groot. Default bij mij is dat slechts 1MB, niet genoeg om de foto’s in op te slaan. Gelukkig kan je de ruimte vergroten met een call naar IncreaseQuotaTo(long newQuotaSize); Deze geeft een boolean terug om aan te geven of het gelukt is of niet. Dus:&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;OpenFileDialog&lt;/span&gt; ofd = &lt;span class="cb2"&gt;new&lt;/span&gt; &lt;span class="cb1"&gt;OpenFileDialog&lt;/span&gt;();&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;if&lt;/span&gt; (ofd.ShowDialog().GetValueOrDefault() == &lt;span class="cb2"&gt;true&lt;/span&gt;)&lt;/p&gt;    &lt;p class="cl"&gt;{&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;var&lt;/span&gt; chosenFileSize = ofd.File.Length;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;// Haal de locatie op voor de applicatie&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;IsolatedStorageFile&lt;/span&gt; isf = &lt;span class="cb1"&gt;IsolatedStorageFile&lt;/span&gt;.GetUserStoreForApplication();&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;if&lt;/span&gt; (isf.Quota &amp;lt; chosenFileSize)&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;if&lt;/span&gt; (isf.IncreaseQuotaTo(chosenFileSize))&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;// Kopieer het bestand&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;else&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb3"&gt;// Toon een error...&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p class="cl"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Maar… wat ik ook probeer, de IncreaseQuotaTo blijft false teruggeven. Ik krijg simpelweg niet de ruimte die ik heb, dus ik kan mijn bestanden niet kopieren. Tijd om te onderzoeken wat er gebeurd. Om het testen te versnellen haal ik de call naar de OpenFileDialog even weg, zodat mijn method er als volgt uit ziet:&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;// 16 MB moet voor nu genoeg zijn&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;var&lt;/span&gt; chosenFileSize = (16 * 1024 * 1024);&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb3"&gt;IsolatedStorageFile&lt;/span&gt; isf = &lt;span class="cb3"&gt;IsolatedStorageFile&lt;/span&gt;.GetUserStoreForApplication();&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;if&lt;/span&gt; (isf.Quota &amp;lt; chosenFileSize)&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;if&lt;/span&gt; (isf.IncreaseQuotaTo(chosenFileSize))&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;// Kopieer het bestand&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;else&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;// Toon een error...&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;En bij het runnen krijg ik nu de volgende dialog:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/6d876efc7aba_87E7/image_3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/6d876efc7aba_87E7/image_thumb_3.png" width="568" height="270" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ok. Dit werkt dus. Nou ja, ik heb het druk, ik zoek het later wel uit, dacht ik. Ik reserveer gewoon 16MB, ze mogen immers maar 4 foto’s maximaal uploaden dus dat moet genoeg zijn. Komt ‘ie:&lt;/p&gt;  &lt;div class="cf"&gt;   &lt;p class="cl"&gt;&lt;span class="cb1"&gt;// 16 MB moet voor nu genoeg zijn&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;var&lt;/span&gt; chosenFileSize = (16 * 1024 * 1024);&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb3"&gt;IsolatedStorageFile&lt;/span&gt; isf = &lt;span class="cb3"&gt;IsolatedStorageFile&lt;/span&gt;.GetUserStoreForApplication();&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;if&lt;/span&gt; (isf.Quota &amp;lt; chosenFileSize)&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;if&lt;/span&gt; (!(isf.IncreaseQuotaTo(chosenFileSize)))&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;// Toon fout en stop&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb2"&gt;return&lt;/span&gt;;&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb3"&gt;OpenFileDialog&lt;/span&gt; ofd = &lt;span class="cb2"&gt;new&lt;/span&gt; &lt;span class="cb3"&gt;OpenFileDialog&lt;/span&gt;();&lt;/p&gt;    &lt;p class="cl"&gt;&lt;span class="cb2"&gt;if&lt;/span&gt; (ofd.ShowDialog().GetValueOrDefault() == &lt;span class="cb2"&gt;true&lt;/span&gt;)&lt;/p&gt;    &lt;p class="cl"&gt;{&lt;/p&gt;    &lt;p class="cl"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="cb1"&gt;// Kopieer het bestand...&lt;/span&gt;&lt;/p&gt;    &lt;p class="cl"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Niet dus. Ik krijg nu een error bij de OpenFileDialog.ShowDialog: SecurityException: Dialogs must be user-initiated. WTF? Ik zit in de BtnClick event handler, hoezo “must be user-initiated?”.&lt;/p&gt;  &lt;p&gt;Na enig nadenken wordt het me iets duidelijker. In mijn code heb ik 2 dialogs: eerst die van de IsolatedStorage, dan die van de OpenFileDialog. Vreemd genoeg werkt het ook niet als de quota al wel groot genoeg is en ik dus niet die dialog krijg. &lt;/p&gt;  &lt;p&gt;Een zoektocht op het net bevestigde dit: bovenstaand scenario is niet mogelijk. Je moet het in twee stappen doen. Eigenlijk zou ik een button moeten maken die de storage vergroot (alleen weet ik niet met hoeveel want de foto’s zijn nog niet geselecteerd), en dan in een ander event de OpenFileDialog tonen. Maar waar in mijn flow moet ik dat doen? Het is onzin om de gebruiker te vragen om meer opslag ruimte als hij helemaal geen foto’s wil uploaden. Maar blijkbaar is dit de enige oplossing.&lt;/p&gt;  &lt;p&gt;Microsoft, verzin hier iets op. Bovenstaand scenario is een vrij gangbaar iets: kies bestanden, dan reserveer je de ruimte. &lt;/p&gt;  &lt;p&gt;Nu weet je het: dit gaat dus niet werken.&lt;/p&gt;  &lt;p&gt;PS Ik heb het probleem wel opgelost: de OpenFileDialog.File is een FileInfo object, en die sla ik nu op in mijn viewmodel in plaats van het pad wat ik eerst van plan was. Daarmee kan ik later de foto’s gaan uploaden. Op die manier heb ik de hele IsolatedStorage niet meer nodig. &lt;/p&gt;  &lt;p&gt;Waarom de FileInfo wel benaderd mag worden maar het pad niet, is mij een raadsel. Maar in ieder geval werkt mijn code nu volgens de flow die we bedacht hadden.&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1071" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1021.aspx">Silverlight</category></item><item><title>DispatcherTimer kostte mij mijn nachtrust</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/07/26/1066.aspx</link><pubDate>Mon, 26 Jul 2010 09:08:15 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1066</guid><dc:creator>dvroegop</dc:creator><slash:comments>1</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1066.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1066</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1066.aspx</wfw:comment><description>&lt;p&gt;Je kent het wel. Het project is &lt;em&gt;bijna&lt;/em&gt; af, je moet alleen nog een paar kleine puntjes oplossen. "Uurtje werk" denk je en je gaat zitten om het allemaal netjes af te ronden. Alles is getest, alleen de gebruikers hebben nog een klein dingetje in de user interface gevonden. Kan niet al te spannend zijn, nietwaar?&lt;/p&gt;  &lt;p&gt;Ik zat vorige week ook in een dergelijke situatie. We hebben een project gedaan op Microsoft Surface en alles was eigenlijk prima. Er was alleen een klein puntje. &lt;/p&gt;  &lt;p&gt;Het systeem geeft informatie over een bouwproject. Er is een 3D model van het bouwterrein en gebruikers kunnen een gebouw selecteren. Als ze dat doen krijgen ze een soort van popup (geen echte, die bestaan niet in Surface) met meer info. Een onderdeel van die extra informatie zijn foto's van het bouwterrein. Gebruikers kunnen nu een foto pakken, die verslepen van de popup en op het hoofdscherm plaatsen. Als ze dat doen wordt de foto daar weergegeven en kunnen zie die vergroten, roteren, verplaatsten, affijn: alle dingen die Surface zo leuk maken.&lt;/p&gt;  &lt;p&gt;Maar om te voorkomen dat het scherm volloopt halen we de popup weg na 30 seconden van inactiviteit. Uiteraard nemen we gelijk de foto's mee als dat gebeurt. We willen niet dat de foto's achterblijven terwijl het informatiescherm al weg is.&lt;/p&gt;  &lt;p&gt;Nu kreeg ik de melding dat de foto's af en toe spontaan verdwenen. Typisch een opmerking van een gebruiker zou je denken, het is wat vaag. Maar goed, ik ging het testen. Ik startte de Surface op, koos een willekeurig gebouw, zag de info, plaatste een foto op het scherm en wachtte op de timeout van 30 seconden. En ja hoor: het informatiescherm ging weg en de foto's verdwenen ook keurig. Precies zoals het hoorde. Ik pakte een paar andere gebouwen maar overal werkte het zoals het hoorde. Natuurlijk werkte dat goed! De gebruikers snapten het niet.&lt;/p&gt;  &lt;p&gt;Tegelijkertijd kwam er iemand langs die onze Surface app wel even wilde zien. Hij ging spelen met ons systeem en toen gebeurde het: ik zag dat hij een informatie paneel opende, een foto pakte en die foto verdween na ongeveer 3 seconden al van het scherm. Vreemd. ik had het toch getest? Het was 4 uur 's middags, de volgende dag moesten we de definitieve oplevering doen. Nou ja, dit kon geen groot probleem zijn, dacht ik.&lt;/p&gt;  &lt;p&gt;Eerst proberen om het probleem te localiseren. Wanneer gebeurde dit nou precies? Na lang experimenteren ontdekte ik dat het gebeurde bij de volgende stappen:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Kies een gebouw&lt;/li&gt;    &lt;li&gt;Open het informatie paneel&lt;/li&gt;    &lt;li&gt;Kies een foto&lt;/li&gt;    &lt;li&gt;Wacht tot het informatiepaneel en de foto vanzelf weggaan&lt;/li&gt;    &lt;li&gt;Wacht even&lt;/li&gt;    &lt;li&gt;Kies &lt;strong&gt;hetzelfde&lt;/strong&gt; gebouw&lt;/li&gt;    &lt;li&gt;Kies &lt;strong&gt;dezelfde&lt;/strong&gt; foto&lt;/li&gt;    &lt;li&gt;En kijk: de foto verdwijnt voor het informatiepaneel weggaat!&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Zucht. Toch iets meer dan een uurtje werk, dacht ik toen.&lt;/p&gt;  &lt;p&gt;Als ik in de code van de applicatie keek, zag ik dat de method die er voor zorgt dat foto's (geanimeerd) van het scherm verdwijnen alleen maar werd aangeroepen vanuit de method die de informatiepanelen verwijderd. Nergens anders vond een call plaats naar die method. En inderdaad: de code die het informatiepaneel opruimt werd aangeroepen terwijl de timeout van het informatiepaneel nog niet verstreken was. Het informatiepaneel zelf bleef ook keurig staan. Vreemd. Heel vreemd. In die code verwijder in de ViewModel van het informatiepaneel uit de Items property van de ScatterView (voor diegene die Surface niet kennen: een ScatterView is een listbox on steroids, meer hoef je nu niet te weten). In de items komt dat hele viewmodel niet voor dus hoe kan het dat die method aangeroepen wordt?&lt;/p&gt;  &lt;p&gt;Ik maak gebruik van een timer in de View van het informatiepaneel. Die timer wordt iedere keer gereset als er iets op het informatiepaneel gebeurt. Als er na 30 seconden geen activiteit is geweest roep ik de ViewModel (die in de DataContext van de View staat) aan en zorg ervoor dat de boel opgeruimd wordt. Hoe kan het dan dat een ViewModel die niet in de Items staat wordt aangeroepen? En hoe kan het dat de View blijft staan op het scherm maar dat zijn foto's wel weg gaan?&lt;/p&gt;  &lt;p&gt;Ik zal je mijn verdere zoektoch besparen, maar rond 4 uur 's nachts had ik het gevonden:&lt;/p&gt;  &lt;p&gt;Bij het opruimen van een informatiepaneel ga ik zoeken naar alle items in de ScatterView die als ViewModel een PhotoViewModel hebben, die ook voorkomt in de PhotoViewModel collectie in mijn informatiepaneel viewmodel. Als die er zijn, laat ik die geanimeerd verdwijnen. Er zat ergens in het geheugen een verwijzing naar een ViewModel van een infopaneel die toevallig dezelfde data bevat als het huidig getoonde informatiepaneel. Aangezien de spook infoViewModel dezelfde foto's bevat als die momenteel op het scherm staan, worden deze weggehaald. Het is echter niet hetzelfde ViewModel als die nu de informatie op het scherm zet, dus de huidige blijft zichtbaar. Dat deel van het mysterie was opgelost. Maar hoe kan het nu dat de oude ViewModels nog in het geheugen staan? Ik had ze toch na de animatie opgeruimd? En inderdaad: ik gooi ze echt weg uit de Items collectie. Voor de zekerheid zet ik ze zelfs op null, maar dat mocht niet baten.&lt;/p&gt;  &lt;p&gt;Ik besloot uiteindelijk maar om te kijken of het zou helpen als ik de timer uit de View haalde en in de ViewModel plaatste. Niet dat ik wist &lt;em&gt;waarom&lt;/em&gt;&amp;#160; dat zou helpen maar het was na vieren 's nachts en ik zag het allemaal niet zo helder meer.&lt;/p&gt;  &lt;p&gt;Om de timer in de ViewModel te plaatsen moest ik uiteraard de juiste references in mijn library project hebben, dus die zocht ik even op in de help. En toen viel mijn oog op de volgende regel:&lt;/p&gt;  &lt;p&gt;A &lt;strong&gt;DispatcherTimer&lt;/strong&gt; will keep an object alive whenever the object's methods are bound to the timer.&lt;/p&gt;  &lt;p&gt;Ah. Oh ja. Dat uhm, wist ik ergens ook wel.. maar helemaal niet meer aan gedacht. De views hebben een timer, en uiteraard een handler gekoppeld aan het Tick event. En in de help staat heel duidelijk dat de timer het object 'alive' houdt als er een method gekoppeld is aan het event. Met andere woorden: ik kan ze verwijderen uit hoeveel collecties ik ook maar wil, ik kan alle variabelen die verwijzen naar de views (en dus de ViewModel die de datacontext is) op null zetten, maar de CLR houdt het object levend en dus zal iedere 30 seconden de Tick genereerd worden. En dus zullen alle foto's behorende bij het object in de ViewModel na 30 seconden opgeruimd worden. De 30 seconden interval gaat lopen na de eerste keer dat deze info getoond wordt en blijft lopen.&lt;/p&gt;  &lt;p&gt;De oplosing was simpel uiteraard: in de tick event handler even _Timer.Tick -= TickHandler toevoegen en het probleem was opgelost.&lt;/p&gt;  &lt;p&gt;Programmeren kan af en toe zo simpel zijn.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:95cfaf3e-8d24-42f6-9b44-71d49e5a644d" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Surface" rel="tag"&gt;Surface&lt;/a&gt;,&lt;a href="http://technorati.com/tags/MVVM" rel="tag"&gt;MVVM&lt;/a&gt;,&lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;&lt;/div&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1066" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1008.aspx">C#</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1020.aspx">Surface</category></item><item><title>MVVM voor beginners, de categorieen</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/06/25/1064.aspx</link><pubDate>Fri, 25 Jun 2010 07:56:19 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1064</guid><dc:creator>dvroegop</dc:creator><slash:comments>1</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1064.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1064</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1064.aspx</wfw:comment><description>&lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dennis_blog/archive/2010/06/24/1063.aspx" target="_blank"&gt;Vorige keer&lt;/a&gt; begon ik een reeks artikelen over MVVM. In dit tweede deel ga ik verder met het voorbeeld dat ik daar begonnen ben en ga ik de categorieen uitbreiden.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Specificaties&lt;/h3&gt;  &lt;p&gt;De klant wil graag voor iedere categorie van een contact een kleurtje zien. Net als in Outlook dus. Voor de eerste versie hebben we twee categorieen, namelijk Prive (geel) en zakelijk (blauw). Een contact kan 0, 1, of meerdere categorieen hebben, deze moeten bij de contact getoond worden.&lt;/p&gt;  &lt;p&gt;Simpel dus.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Implementatie&lt;/h3&gt;  &lt;p&gt;We hebben de Category class al gedefinieerd. Laten we de ViewModel maken. Ook deze implementeert INotifyPropertyChanged, net zoals de ContactViewModel, dus het is handig om een baseclass te maken en ContactViewModel en CategoryViewModel hiervan af te leiden:&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.ComponentModel;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;namespace&lt;/span&gt; dotNedContactManager.ViewModels&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;abstract&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ViewModelBase&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;INotifyPropertyChanged&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;event&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;PropertyChangedEventHandler&lt;/span&gt; PropertyChanged;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;protected&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; RaisePropertyChanged(&lt;span style="color: blue"&gt;string&lt;/span&gt; propertyName)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; eventCopy = PropertyChanged;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (eventCopy == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; eventCopy( &lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;PropertyChangedEventArgs&lt;/span&gt;( propertyName ) );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;We moeten nu wel even ContactViewModel aanpassen: het event eruit, de RaisePropertyChanged eruit, en niet meer INotifyPropertyChanged implementeren maar afleiden van ViewModelBase. Voor CategoryView ziet het er dan als volgt uit:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; dotNedContactManager.Model;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace&lt;/span&gt; dotNedContactManager.ViewModels&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;ViewModelBase&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; _Category;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; CategoryViewModel(&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; category)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (category == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;throw&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;( &lt;span style="color: #a31515"&gt;&amp;quot;category&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;category is null.&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Category = category;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;string&lt;/span&gt; Description&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; _Category.Description; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Category.Description = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RaisePropertyChanged( &lt;span style="color: #a31515"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// Deze hebben we nodig in de ContactViewModel.&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;internal&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; Category&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; _Category; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;In ContactViewModel voegen we nu de Categories toe (die hadden we nog niet). &lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt;&amp;gt; _Categories;&lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt;&amp;gt; Categories&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; _Categories;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;De Categories is een ObservableCollection&amp;lt;CategoryViewModel&amp;gt;, wat inhoudt dat als er een wijziging op de collectie optreedt we daar iets mee kunnen doen. In de constructor van onze ViewModel maken we de Categories aan en zetten de events. We moeten de constructor dus aanpassen:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; ContactViewModel(&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt; contact)&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (contact == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;throw&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;( &lt;span style="color: #a31515"&gt;&amp;quot;contact&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;contact is null.&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; _Contact = contact;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; _Categories = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ObservableCollection&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt;&amp;gt;();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; category &lt;span style="color: blue"&gt;in&lt;/span&gt; contact.Categories)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Categories.Add( &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt;( category ) );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; _Categories.CollectionChanged += Categories_CollectionChanged;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;We zetten de eventhandler pas na het vullen van de initiele collectie, anders gebeuren er rare dingen. En deze hebben we ook nodig: de implementatie van de Categories_CollectionChanged:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; Categories_CollectionChanged(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;NotifyCollectionChangedEventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// Wijzig de categorieeen in de Contact &lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;switch&lt;/span&gt; (e.Action)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;case&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NotifyCollectionChangedAction&lt;/span&gt;.Add:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt; newCategory &lt;span style="color: blue"&gt;in&lt;/span&gt; e.NewItems)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Contact.Categories.Add( newCategory.Category );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;case&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;NotifyCollectionChangedAction&lt;/span&gt;.Remove:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CategoryViewModel&lt;/span&gt; oldCategory &lt;span style="color: blue"&gt;in&lt;/span&gt; e.OldItems)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Contact.Categories.Remove( oldCategory.Category );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;default&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// etc...&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Zo gauw er in de ViewModel iets verandert met de Categories van de Contact, sturen we dit direct door naar onze domeinclass Contact. Je hoeft dit niet te doen, maar voor nu is dat wel zo handig.&lt;/p&gt;

&lt;p&gt;We gaan nu een tweetal views maken. Een voor de Category maar ook een voor de CategoryCollection. Die laatste is niets anders dan een lijst met CategoryViews maar is wel handig. Zie:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: red"&gt; x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;dotNedContactManager.Views.CategoryView&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; mc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Ignorable&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; d&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;DesignHeight&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; d&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;DesignWidth&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; Description&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;En de lijst:&lt;/p&gt;

&lt;p&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: red"&gt; x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;dotNedContactManager.Views.CategoryListView&amp;quot;&lt;/span&gt; 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt; 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt; 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;views&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;clr-namespace:dotNedContactManager.Views&amp;quot;&lt;/span&gt; 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot;&lt;/span&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Ignorable&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;DesignHeight&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; d&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;DesignWidth&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox&lt;/span&gt;&lt;span style="color: red"&gt; ItemsSource&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;views&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;CategoryView&lt;/span&gt;&lt;span style="color: red"&gt; DataContext&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;DataTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox.ItemTemplate&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;ListBox&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;

  &lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Nu alleen de categorieen toevoegen in onze ContactView. We hebben een namespace nodig:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;views&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;clr-namespace:dotNedContactManager.Views&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;En de view zelf:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;views&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;CategoryListView&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; DataContext&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; Categories&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Ik hoop dat je al die Bindings nog kunt volgen. Even voor de duidelijkheid:&lt;/p&gt;

&lt;p&gt;In MainWindow maken we een instance van ContactView. Deze krijgt de DataContext van de ContactViewModel. In de ContactView staan bindings naar FirstName, LastName, FullName en Categories. Dit zijn allen properties van ContactViewModel, dus die worden gevonden. Echter, de CategoryListView krijgt een binding op de datacontext ({Binding Categories}). Dus in de CategoryListView hebben we nu een DataContext (te weten: een ObservableCollection&amp;lt;CategoryView&amp;gt;). Dit wordt gebruikt als bron voor de ListBox.ItemsSource. We geven bij Binding daar geen pad op, dus hij krijgt het gehele object, i.e. de ObservableCollection. Vervolgens wordt er voor ieder item in die collection een CategoryView aangemaakt, deze krijgt als DataContext dit item mee (dus een CategoryViewModel uit de ObservableCollection).&amp;#160; In de CategoryView hebben we nu dus een DataContext, wat in dit geval een instance van CategoryViewModel is, en die heeft de property Description. Die wordt getoond in een textbox.&lt;/p&gt;

&lt;p&gt;Je ziet dat alles aan elkaar gelinkt wordt door bindings en niets in de code. &lt;/p&gt;

&lt;p&gt;Voor je runt moet je uiteraard nog wel even de juiste data meegeven in MainWindow.xaml.cs:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;partial&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;MainWindow&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Window&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt; ContactVM { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; MainWindow()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DataContext = &lt;span style="color: blue"&gt;this&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// Tijdelijk wat data genereren&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Model.&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt; newContact = &lt;span style="color: blue"&gt;new&lt;/span&gt; Model.&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt;()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = &lt;span style="color: #a31515"&gt;&amp;quot;Dennis&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = &lt;span style="color: #a31515"&gt;&amp;quot;Vroegop&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Model.&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; catPrivate = &lt;span style="color: blue"&gt;new&lt;/span&gt; Model.&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;() { Description = &lt;span style="color: #a31515"&gt;&amp;quot;Prive&amp;quot;&lt;/span&gt; };&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Model.&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt; catBusiness = &lt;span style="color: blue"&gt;new&lt;/span&gt; Model.&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;() { Description = &lt;span style="color: #a31515"&gt;&amp;quot;Zakelijk&amp;quot;&lt;/span&gt; };&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; newContact.Categories.Add( catPrivate );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; newContact.Categories.Add( catBusiness );&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ContactVM = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt;( newContact );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;We maken even snel twee categorieen aan en geven deze mee aan ons Contact. &lt;/p&gt;

&lt;p&gt;Run en zie:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginnersdecategorieen_A65C/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginnersdecategorieen_A65C/image_thumb.png" width="529" height="354" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Leuk, niet waar? Is alleen nog niet conform specificaties. We willen geen tekstuele beschrijving van de categorie, maar een vierkantje met een kleur..&lt;/p&gt;

&lt;p&gt;Hoe gaan we dat nu doen? Deze specificatie is alleen van belang bij de User Interface. Het domein verandert niet, en eigenlijk ook de ViewModel niet. Alleen de UI moet wat anders laten zien. En dit is nu precies de kracht van MVVM: dit soort designdingen kun je overlaten aan diegene die bezig is met de UI: de onderliggende lagen veranderen niet.&lt;/p&gt;

&lt;p&gt;We willen dus een andere view voor Category, dus CategoryView moet anders. Geen probleem. We maken een andere XAML, maar we voegen wel iets toe. Om precies te zijn: we maken een converter. Een converter is een class die wordt gebruikt voor het converteren van een bepaald type naar een ander type in Bindings. Bijvoorbeeld: het converteren van een string met een bepaalde waarde naar een kleur.. Eerst de converter schrijven:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Windows.Data;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Windows.Media;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;namespace&lt;/span&gt; dotNedContactManager.Converters&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;DescriptionToBrushConverter&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IValueConverter&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; Convert(&lt;span style="color: blue"&gt;object&lt;/span&gt; value, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; targetType, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;object&lt;/span&gt; parameter, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Globalization.&lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt; culture)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (!(value &lt;span style="color: blue"&gt;is&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;))&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; value;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; cleanedString = ((&lt;span style="color: blue"&gt;string&lt;/span&gt;)value).Trim().ToUpper();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty( cleanedString ))&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Brushes&lt;/span&gt;.White;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;switch&lt;/span&gt; (cleanedString)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;case&lt;/span&gt;&amp;#160;&lt;span style="color: #a31515"&gt;&amp;quot;PRIVE&amp;quot;&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Brushes&lt;/span&gt;.Yellow;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;case&lt;/span&gt;&amp;#160;&lt;span style="color: #a31515"&gt;&amp;quot;ZAKELIJK&amp;quot;&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Brushes&lt;/span&gt;.Blue;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;default&lt;/span&gt;:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Brushes&lt;/span&gt;.HotPink;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;object&lt;/span&gt; ConvertBack(&lt;span style="color: blue"&gt;object&lt;/span&gt; value, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt; targetType, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;object&lt;/span&gt; parameter, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.Globalization.&lt;span style="color: #2b91af"&gt;CultureInfo&lt;/span&gt; culture)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// Negeren we voor nu, we gaan &lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// geen brushes terugconverteren naar strings&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; value;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;We krijgen een string binnen, we kijken naar de inhoud en geven een SolidColorBrush met een bepaalde kleur terug. Als we geen string krijgen, krijgen we een witte brush, als we een andere categorie krijgen dan we verwachten dan wordt hij mooi roze (zodat hij goed opvalt en we weten dat we een bug ergens hebben).&lt;/p&gt;

&lt;p&gt;We passen de CategoryView even aan:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: red"&gt; x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;dotNedContactManager.Views.CategoryView&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;converters&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;clr-namespace:dotNedContactManager.Converters&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;64&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;64&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;converters&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;DescriptionToBrushConverter&lt;/span&gt;&lt;span style="color: red"&gt; x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Key&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;descToBrushConv&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl.Resources&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Border&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; BorderBrush&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;#8D8D8D&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; BorderThickness&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; CornerRadius&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; Background&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; Description&lt;/span&gt;&lt;span style="color: blue"&gt;,&lt;/span&gt;&lt;span style="color: red"&gt; Converter&lt;/span&gt;&lt;span style="color: blue"&gt;={&lt;/span&gt;&lt;span style="color: #a31515"&gt;StaticResource&lt;/span&gt;&lt;span style="color: red"&gt; descToBrushConv&lt;/span&gt;&lt;span style="color: blue"&gt;}}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; Description&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; Foreground&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Black&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; HorizontalAlignment&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Center&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Border&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Ik heb een namespace aangemaakt die verwijst naar de converters. In de Resources heb ik nu die converter aangemaakt en een key gegeven. Om de originele Textblock die we al hadden is nu een Border geplaatst.&lt;/p&gt;

&lt;p&gt;De border heeft een BackGround en die wordt gebind aan Description. Uiteraard is Description een string en geen Brush, maar daar zorgt onze converter voor. Die maakt een mooie brush aan naar gelang de waarde van de description.&lt;/p&gt;

&lt;p&gt;Runnen maar:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginnersdecategorieen_A65C/image_3.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginnersdecategorieen_A65C/image_thumb_3.png" width="541" height="424" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Stukken beter, niet waar? Een echte designer kan hier nu mee aan de gang en zich helemaal uitleven op dit soort schermen. Alle logica is immers los van de frontend. En wat de designer ook doet, zolang de Bindings er maar blijven staan werkt het allemaal wel. Wij als ontwikkelaars kunnen verder gaan met het schrijven van code voor ViewModels (en dus ook de unittests die daarbij horen).&lt;/p&gt;

&lt;p&gt;Volgende keer meer!&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:948169f0-4bf5-4891-aa43-7d6640d4d9a5" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/MVVM" rel="tag"&gt;MVVM&lt;/a&gt;,&lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;&lt;/div&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1064" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1008.aspx">C#</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1017.aspx">WPF</category></item><item><title>MVVM voor beginners</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/06/24/1063.aspx</link><pubDate>Thu, 24 Jun 2010 09:43:12 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1063</guid><dc:creator>dvroegop</dc:creator><slash:comments>2</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1063.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1063</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1063.aspx</wfw:comment><description>&lt;p&gt;Model View ViewModel, kortweg MVVM. Als je met WPF of Silverlight bezig bent, ben je deze vast tegen gekomen. Op het internet zijn momenteel erg veel discussies over dit onderwerp gaande. Wat is de beste aanpak? Welk framework kun je het beste gebruiken? Hoe ga je om met dialogs? Het begint bijna op een religieuze strijd te worden, de voorstanders van de ene aanpak vliegen de tegenstanders regelmatig in de haren.&lt;/p&gt;  &lt;p&gt;Als je geen ervaring hebt met MVVM lijkt dit allemaal een beetje overdreven. Immers, we hebben het maar over een pattern, oftewel een manier van werken die we allemaal wel kennen maar die we maar even een naam gegeven hebben. En als je zo denkt, dan heb je volgens mij gelijk. &lt;/p&gt;  &lt;p&gt;Toch is MVVM een heel mooie pattern. Het stelt mij in ieder geval in staat om mijn WPF/Silverlight code netjes te structureren en alle logica in mijn applicatie perfect testbaar in unittests te maken. Dat laatste alleen al is volgens mij een goede reden om MVVM eens te bekijken.&lt;/p&gt;  &lt;p&gt;Voor iedereen die al met MVVM werkt: sla deze post gerust over. Ik ga hier nog veel meer over schrijven en wellicht is dat interessanter. Voor de rest: ik ga hier uitleggen wat MVVM is en hoe je het toepast. &lt;/p&gt;  &lt;h3&gt;Frameworks&lt;/h3&gt;  &lt;p&gt;De vraag die ik het meest gesteld krijg van mensen die met MVVM beginnen is: welk framework kan ik het beste gebruiken? Het antwoord daarop is altijd: geen. Maak zelf een framework.&lt;/p&gt;  &lt;p&gt;Nu ben ik in het algemeen geen voorstander van het opnieuw uitvinden van het wiel, maar in dit geval raad ik het toch aan. MVVM is niet ingewikkeld en de frameworks die er zijn hebben niet al te veel features (hoewel sommige wel hele slimme oplossingen hebben bedacht). Ga eerst een zelf aan de gang, zorg dat je de concepten begrijpt en dat je weet wat MVVM inhoudt. Als je dat eenmaal in de vingers hebt, kun je gaan kijken naar MVVMFoundations, MVVMLight en de andere varianten.&lt;/p&gt;  &lt;p&gt;In deze blogpost ga ik uitleggen wat MVVM is en hoe het werkt, we beginnen gelijk met het bouwen van onze eigen MVVM framework. Zullen we hem DutchMVVM noemen? Nah..&lt;/p&gt;  &lt;h3&gt;Achtergrond&lt;/h3&gt;  &lt;p&gt;MVVM is niets nieuws. Het is een variant op de oudere, meer bekende MVP en MVC patterns die al jaren gepropageerd worden door mensen als Martin Fowler. Ze gaan allemaal uit van hetzelfde principe: scheiding van je userinterface, je business logica en je domeinmodel. Voor al deze patterns geldt het volgende plaatje:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginners_8A5E/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginners_8A5E/image_thumb.png" width="415" height="343" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We hebben in principe drie lagen. Iedere laag heeft zijn eigen verantwoordelijkheid. De UI laag bevat alle grafische componenten zoals textboxen, labels, buttons, listboxen en wat niet meer. De domein laag bevat je classes met daarin je business objecten, zoals een Contact class, een Order class enzovoorts. De laag daartussen, de logica laag, koppelt de andere twee aan elkaar en bevat de logica. &lt;/p&gt;  &lt;p&gt;Ik hoor je al zeggen: maar wij hebben meer lagen! Dat is natuurlijk in de praktijk zo, maar je kunt, als het goed is, iedere applicatie opdelen op bovenstaande manier. Zelfs als je een eenvoudige ASP.Net HelloWorld maakt heb je dit principe. Je ASPX pagina is je UI, je CodeBehind bevat de logica en de data die je weergeeft (in het geval van HelloWorld alleen de string "Hello World!") is je domein model.&lt;/p&gt;  &lt;p&gt;Het maakt de patterns niet uit hoe je domein laag eruit ziet. Je kunt deze zelf schrijven, genereren met Linq to SQL, Entity Framework gebruiken, of wat je maar wilt. Het belangrijkste is echter dat je domeinlaag geen kennis heeft van de lagen daarboven. Hetzelfde geldt voor je tussenlaag: die moet wel kennis hebben van je domeinlaag, maar mag niets weten van de UI laag. En als laatste: je UI laag heeft wel weet van je BL laag maar niet van je domeinlaag.&lt;/p&gt;  &lt;p&gt;Als je je applicaties op die manier structureert zie je dat je je lagen later kunt aanpassen zonder grote impact op de rest van je systeem. MVVM zorgt er zelfs voor dat je je BL laag (of zoals dat daar heet: je ViewModel) en je domeinmodel los kunt testen in een testomgeving, zonder last te hebben van je User Interface. &lt;/p&gt;  &lt;p&gt;MVVM is specifiek bedoelt voor WPF en Silverlight. Het maakt gebruik van de enorme kracht van Bindings in die platformen. Hierdoor kunnen we losse lagen schrijven die echt onafhankelijk zijn van de laag erboven.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Binding in WPF/SL&lt;/h3&gt;  &lt;p&gt;Ik ga hier niet uitgebreid in op de werking van Bindings in WPF en SL. Daar zijn genoeg andere bronnen van informatie over. Maar even een hele kleine achtergrond is wel op zijn plaats.&lt;/p&gt;  &lt;p&gt;Binding zorgt ervoor dat de elementen op het scherm gevuld worden met gegevens die ergens anders vandaan komen. Met andere woorden: een textbox bevat een string die niet in de definitie van je scherm staat maar die een andere oorsprong heeft.&lt;/p&gt;  &lt;p&gt;Om dat te bereiken zijn er twee elementen in WPF van belang. Als eerste is er de content van je control. Een Textbox heeft bijvoorbeeld een Text property, een Button heeft een Content Property. Dit zijn allemaal dependencyproperties en dependencyproperties kun je binden aan iets anders.&lt;/p&gt;  &lt;p&gt;Een Binding geeft aan hoe de data opgehaald moet worden. De data zelf kan van alles zijn. Van een eenvoudige string tot aan een complete usercontrol, zolang de property die gebind wordt er mee overweg kan kun je het via binding erin stoppen.&lt;/p&gt;  &lt;p&gt;In XAML ziet een Binding er bijvoorbeeld als volgt uit:&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; Path&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;MyText&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;In plaats van een hardcoded string in de TextBox te plaatsen, vertellen we WPF nu dat er ergens een property is met de naam MyText en de inhoud daarvan willen we graag in de TextBox zien.&lt;/p&gt;

&lt;p&gt;Maar waar staat die MyText property dan? Dat is de taak van de DataContext. De DataContext geeft aan wat de bron is van de Bindings. Dus: de DataContext geeft aan &lt;em&gt;waar&lt;/em&gt; de data staat, de binding specificeert &lt;em&gt;wat&lt;/em&gt; er moet staan. Die twee elementen zijn genoeg om de binding te maken.&lt;/p&gt;

&lt;p&gt;Om aan te geven dat de MyText property een property is van de huidige window, moeten we even wat kunstgrepen uithalen. Voor nu nemen we even de makkelijkste weg. In de codebehind van ons scherm plaatsen we in de constructor de volgende regel:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; MainWindow()&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DataContext = &lt;span style="color: blue"&gt;this&lt;/span&gt;;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;We zetten de DataContext dus op zichzelf. Als je nu in je window een property MyText hebt (van het type String), zal de inhoud van die property in de textbox geplaatst worden. En andersom: als je de textbox wijzigt, zal die nieuwe waarde in MyText terechtkomen! Er is nog veel meer te vertellen over Bindings, als je meer wilt weten raad ik je aan om &lt;a href="http://www.bing.com/search?q=wpf+binding&amp;amp;form=OSDSRC" target="_blank"&gt;deze link&lt;/a&gt; te volgen.&lt;/p&gt;

&lt;p&gt;Maar: je ziet dat je door Bindings te gebruiken in staat bent om de data ergens neer te zetten en dan in de UI laag aan te geven waar deze data staat. Je hoeft dus niet meer in je logica data naar je UI te kopieren, je UI laag haalt het zelf wel op. Zie je MVVM al een beetje voor je?&lt;/p&gt;

&lt;h3&gt;MVVM&lt;/h3&gt;

&lt;p&gt;MVVM zou niet mogelijk zijn zonder de binding technieken in WPF en Silverlight. Laten we de verschillende onderdelen eens onder de loep nemen.&lt;/p&gt;

&lt;p&gt;Het idee is dat je voor alles wat op het scherm gaat komen usercontrols maakt. Deze noemen we de views. Een view bevat alle UI elementen die je nodig hebt om je data weer te geven en/of te bewerken. Alle data in dat scherm wordt door middel van databinding gekoppeld.&lt;/p&gt;

&lt;p&gt;Je model is simpelweg je domeinmodel. Zoals al eerder gezegd kunnen die gewone classes zijn, of iets uit NHibernate, of wat dan ook. Er hoeft in principe geen relatie te bestaan tussen je UI en je model: deze kunnen los ontwikkeld worden.&lt;/p&gt;

&lt;p&gt;Het voordeel van deze loskoppeling is dat het nu mogelijk is dat een designer in Blend de UI aanmaakt, terwijl een developer zich bezig houdt met het domein model. Deze twee mensen kunnen los van elkaar werken.&lt;/p&gt;

&lt;p&gt;De lijm die alles met elkaar verbindt is de ViewModel. Laten we eens een voorbeeld nemen.&lt;/p&gt;

&lt;p&gt;Ik neem een simpel voorbeeld: een applicatie die contacten toont. Een contact is een persoon met een voornaam, een achternaam en een lijst met categorieen. Een categorie kan zijn "Prive", "Zakelijk", enzovoorts. Ons domein model ziet er als volgt uit:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginners_8A5E/image_3.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginners_8A5E/image_thumb_3.png" width="440" height="189" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alle properties zijn strings, met uitzondering van Categories, wat een List&amp;lt;Category&amp;gt; is. In de constructor wordt deze laatste aangemaakt, de setter is private zodat we deze niet kunnen wijzigen.&lt;/p&gt;

&lt;p&gt;De View is net zo simpel, met een kanttekening. In de specificaties staat dat boven ieder contact de volledige naam moet staan, dus de voornaam en achternaam samengevoegd. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginners_8A5E/image_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://community.dotned.nl/blogs/dvroegop/MVVMvoorbeginners_8A5E/image_thumb_4.png" width="339" height="333" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Met de XAML:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: red"&gt; x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;dotNedContactManager.Views.ContactView&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;d&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; mc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Ignorable&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;d&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; d&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;DesignHeight&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; d&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;DesignWidth&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;RowDefinition&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;RowDefinition&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;RowDefinition&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;RowDefinition&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ColumnDefinition&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;ColumnDefinition&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.ColumnSpan&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&amp;#160;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; FullName&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; FontSize&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;16&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; FontWeight&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Bold&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Voornaam:&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Achternaam:&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBlock&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;Categorieen:&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; FirstName&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; LastName&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;TextBox&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Row&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Grid.Column&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Text&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; Categories&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;UserControl&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Geen rocketscience, zoals ik al zei.&lt;/p&gt;

&lt;p&gt;In ons domein hebben we geen FullName. Dat hoeft ook niet, want dat hoort niet bij het domein. Het is puur een UI ding: de gebruikers willen graag de volledige naam boven ieder contact hebben. Aangezien het composite is (dus samengesteld) zou het onzinnig zijn om de FullName bijvoorbeeld ook in de database op te slaan.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Het wordt tijd voor onze ViewModel.&lt;/p&gt;

&lt;p&gt;Een ViewModel is een class met als enige bijzonderheid dat hij de interface INotifyPropertyChanged event implementeert. Deze interface bevat een event, PropertyChanged, die moet worden afgevuurd als een property in de class van inhoud wijzigt. Het Binding mechanisme van WPF en SL let op deze events en zal, indien nodig, de Bindings verversen (en dus de nieuwe data op het scherm tonen).&lt;/p&gt;

&lt;p&gt;Komt 'ie:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.ComponentModel;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; dotNedContactManager.Model;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;namespace&lt;/span&gt; dotNedContactManager.ViewModels&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;INotifyPropertyChanged&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;event&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;PropertyChangedEventHandler&lt;/span&gt; PropertyChanged;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; RaisePropertyChanged(&lt;span style="color: blue"&gt;string&lt;/span&gt; propertyName)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;var&lt;/span&gt; eventCopy = PropertyChanged;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (eventCopy == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; eventCopy( &lt;span style="color: blue"&gt;this&lt;/span&gt;, &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;PropertyChangedEventArgs&lt;/span&gt;( propertyName ) );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;private&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt; _Contact;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; ContactViewModel(&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt; contact)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (contact == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;throw&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ArgumentNullException&lt;/span&gt;( &lt;span style="color: #a31515"&gt;&amp;quot;contact&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;contact is null.&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Contact = contact;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;string&lt;/span&gt; FirstName&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; _Contact.FirstName; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Contact.FirstName = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RaisePropertyChanged( &lt;span style="color: #a31515"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RaisePropertyChanged( &lt;span style="color: #a31515"&gt;&amp;quot;FullName&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;string&lt;/span&gt; LastName&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt; _Contact.LastName; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;set&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _Contact.LastName = &lt;span style="color: blue"&gt;value&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RaisePropertyChanged( &lt;span style="color: #a31515"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RaisePropertyChanged( &lt;span style="color: #a31515"&gt;&amp;quot;FullName&amp;quot;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;string&lt;/span&gt; FullName&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;get&lt;/span&gt; { &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;String&lt;/span&gt;.Format( &lt;span style="color: #a31515"&gt;&amp;quot;{0} {1}&amp;quot;&lt;/span&gt;, _Contact.FirstName, _Contact.LastName ); }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;We hebben in onze ViewModel een referentie gelegd naar onze domein class Contact. Zoals ik al eerder zei is dat geen probleem: een bovenliggende laag mag enige kennis hebben van de laag daar direct onder. Voor de eenvoud geef ik deze contact even mee in de constructor; dat gaan we later aanpassen. Voor nu is dat wel even makkelijk zo.&lt;/p&gt;

&lt;p&gt;De ViewModel heeft 3 properties, te weten FirstName, LastName en FullName. De eerste twee halen hun data rechtstreeks uit de _Contact. Als de data verandert, zetten we deze ook direct in _Contact, maar we roepen ook de method RaisePropertyChanged(string propertyName) aan. Deze method vuurt het event af met de juiste propertynaam. Op die manier weet de UI laag dat er iets is verandert en dat de UI dus geupdate moet worden. Maar. aangezien de derde property FullName afhankelijk is van FirstName en LastName, moeten we ook aangeven dat deze gewijzigd is. Immers, als de voornaam wijzigt moeten ook de UI elementen die aan FullName gebonden zijn meeveranderen! FullName is verder readonly: het heeft geen zin om daar een Setter voor te schrijven.&lt;/p&gt;

&lt;p&gt;Laten we de boel eens samenvoegen. In de MainWindow heb ik een property gemaakt van het type ContactViewModel. In de constructor van MainWindow vul ik even wat data in. Nu zit in MainWindow.xaml.cs dus kennis van de Contact class, die geven we immers door aan de ViewModel, en dat is niet zoals het hoort. Later zullen we dit eruit halen, voor nu is dit goed genoeg.&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; System.Windows;&lt;br /&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; dotNedContactManager.ViewModels;&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue"&gt;namespace&lt;/span&gt; dotNedContactManager&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;partial&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;class&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;MainWindow&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Window&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt; ContactVM { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;public&lt;/span&gt; MainWindow()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DataContext = &lt;span style="color: blue"&gt;this&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: green"&gt;// Tijdelijk wat data genereren&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Model.&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt; newContact = &lt;span style="color: blue"&gt;new&lt;/span&gt; Model.&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt;()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = &lt;span style="color: #a31515"&gt;&amp;quot;Dennis&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = &lt;span style="color: #a31515"&gt;&amp;quot;Vroegop&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ContactVM = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt;( newContact );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;En de XAML:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Window&lt;/span&gt;&lt;span style="color: red"&gt; x&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;Class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;dotNedContactManager.MainWindow&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;x&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;views&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;clr-namespace:dotNedContactManager.Views&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: red"&gt; Title&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;MainWindow&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Height&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;350&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt; Width&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;525&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;views&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ContactView&lt;/span&gt;&lt;span style="color: red"&gt; DataContext&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;{&lt;/span&gt;&lt;span style="color: #a31515"&gt;Binding&lt;/span&gt;&lt;span style="color: red"&gt; ContactVM&lt;/span&gt;&lt;span style="color: blue"&gt;}&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a31515"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Grid&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Window&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;Ik heb hier een namespace 'views' toegevoegd, en in het scherm een instance van de ContactView gemaakt. De DataContext van deze view is gebonden aan onze property ContactVM (en aangezien MainWindow als DataContext zichzelf heeft, wordt deze ook gevonden).&lt;/p&gt;

&lt;p&gt;In de ContactView hebben we de bindings {Binding FirstName}, {Binding LastName} en {Binding FullName} staan. Omdat de DataContext gezet wordt op een instance van onze ContactViewModel, worden deze properties ook gevonden en uitgelezen.&lt;/p&gt;

&lt;p&gt;Als je dit nu runt krijg je je scherm te zien. Wanneer je een van de twee naam velden wijzigt, zul je zien dat de FullName meegaat.&lt;/p&gt;

&lt;p&gt;We hebben nu dus in onze UI laag nergens code staan die de teksten neerzet, en ook de logica voor het samenvoegen van de namen is niet terug te vinden in onze UI laag. We kunnen nu dus een unit test maken om onze ViewModel te testen:&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;[&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;void&lt;/span&gt; FullName_Should_Reflect_FirstName_And_LastName()&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;string&lt;/span&gt; firstName = &lt;span style="color: #a31515"&gt;&amp;quot;A&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;string&lt;/span&gt; lastName = &lt;span style="color: #a31515"&gt;&amp;quot;B&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;string&lt;/span&gt; expected = &lt;span style="color: #a31515"&gt;&amp;quot;A B&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt; newContact = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Contact&lt;/span&gt;()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; FirstName = firstName,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LastName = lastName&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; };&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt; contactVM = &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ContactViewModel&lt;/span&gt;( newContact );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual( expected, contactVM.FullName, &lt;span style="color: #a31515"&gt;&amp;quot;FullName doesn't work.&amp;quot;&lt;/span&gt; );&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Alle logica zit nu in de Model en ViewModel classes, we kunnen die dus perfect unittesten. &lt;/p&gt;

&lt;h3&gt;&lt;/h3&gt;

&lt;h3&gt;En nu?&lt;/h3&gt;

&lt;p&gt;Dit is de basis van MVVM. Er is nog veel meer over te vertellen, en dat ga ik doen ook. Maar niet nu. Speel er eens mee en de volgende keer gaan we dieper in op de Category ViewModel. Die is namelijk leuker :-)&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:819ba544-cda7-47d4-9635-04b0104556c7" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/MVVM" rel="tag"&gt;MVVM&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Silverlight" rel="tag"&gt;Silverlight&lt;/a&gt;,&lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;&lt;/div&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1063" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1008.aspx">C#</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1017.aspx">WPF</category></item><item><title>Expression 4 Community Launch bij Sixin!</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/06/03/1059.aspx</link><pubDate>Thu, 03 Jun 2010 06:31:30 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1059</guid><dc:creator>dvroegop</dc:creator><slash:comments>1</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1059.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1059</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1059.aspx</wfw:comment><description>&lt;p&gt;Op 8 juni aanstaande organiseren onze collega's van Sixin, samen met Centric en Microsoft het Expression 4 Community Launch event.&lt;/p&gt;  &lt;p&gt;Ze hebben nog een aantal plaatsen beschikbaar. Daarom nodigt Sixin ook onze leden uit om eens met ze te netwerken, maar vooral om een paar goede sessies bij te wonen.&lt;/p&gt;  &lt;p&gt;Dit event zal worden gehouden in de avond van 8 juni. Tijdens dit event zullen de 2 sprekers van die avond je inlichten over de nieuwe mogelijkheden van versie 4 Expression Blend, Expression Web en Expression Encoder.&lt;/p&gt;  &lt;p&gt;Als je het leuk vindt wacht dan niet en registreer je bij Sixin voor het event:   &lt;br /&gt;&lt;a href="http://sixin.nl/meetings.aspx?eventid=efdd6929-4246-4b6e-921f-a2ac8663b092"&gt;http://sixin.nl/meetings.aspx?eventid=efdd6929-4246-4b6e-921f-a2ac8663b092&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;De agenda ziet er als volgt uit:&lt;/p&gt;  &lt;p&gt;17:45 - 18:45 Eten, drinken en netwerken&lt;/p&gt;  &lt;p&gt;18:45 - 19:00 Ontvangst &amp;amp; introductie door Koen Zwikstra, bestuurslid van Sixin en Silverlight MVP&lt;/p&gt;  &lt;p&gt;19:00 - 20:00 Building a Windows Phone 7 application using the new features of Expression Blend 4 door Loek van den Ouweland, oprichter van en webdesigner bij Toverstudio&lt;/p&gt;  &lt;p&gt;20:00 - 20:15 Pauze&lt;/p&gt;  &lt;p&gt;20:30 - 21:30 Rondleiding door Expression Web en Encoder door Antoni Dol, senior designer bij Macaw&lt;/p&gt;  &lt;p&gt;21:30 - 22:00 Netwerken onder het genot van een drankje&lt;/p&gt;  &lt;p&gt;Uiteraard zijn de Sixin leden ook van harte welkom op de DotNed Events! Hou daarom onze events ook in de gaten, daar zit vast wel iets tussen wat van pas komt!&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1059" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1010.aspx">Events</category></item><item><title>Visual Studio 2010 Community Launch bij Afas</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/04/15/1023.aspx</link><pubDate>Thu, 15 Apr 2010 09:56:03 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1023</guid><dc:creator>dvroegop</dc:creator><slash:comments>1</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1023.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1023</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1023.aspx</wfw:comment><description>&lt;p&gt;Op 20 april organiseren de nederlandse .net communities &lt;a href="http://www.dotned.nl"&gt;dotNed&lt;/a&gt;, &lt;a href="http://www.sdn.nl"&gt;SDN&lt;/a&gt;, &lt;a href="http://www.vbcentral.nl"&gt;VBCentral &lt;/a&gt;en &lt;a href="http://www.sixin.nl"&gt;Sixin &lt;/a&gt;samen met Microsoft de Nederlandse Visual Studio 2010 Launch!&lt;/p&gt;  &lt;p&gt;Deze avond, die gehouden wordt bij &lt;a href="http://www.afas.nl"&gt;Afas &lt;/a&gt;te Leusden, kun je op twee manier bijwonen. Je kunt de avond online volgen of je kunt er bij zijn! Het zal een interactieve gebeurtenis zijn dus laat je deze kans niet voorbij gaan.&lt;/p&gt;  &lt;p&gt;De keynote wordt gegeven door &lt;a href="http://blogs.msdn.com/amit_chatterjee/"&gt;Amit Chatterjee&lt;/a&gt;, verantwoordelijk voor de Visual Studio Test Business bij Microsoft. Na deze keynote zijn er interactieve sessies, gegeven door Alex Thissen, Anko Duizer, Marcel de Vries en Wouter van Vugt.&lt;/p&gt;  &lt;p&gt;Een aantal dotNed bezoekers heeft samen met Sevensteps en Detrio een applicatie gebouwd op Microsoft Surface waarmee we in staat zijn om vragen vanuit het publiek (zowel in de zaal als mensen die online meedoen) te kunnen tonen, beoordelen, er op stemmen en dergelijke. Deze unieke community effort zal voor het eerst gebruikt worden op deze avond, nog een reden om mee te doen.&lt;/p&gt;  &lt;p&gt;Het programma ziet er als volgt uit:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;17:30 - 18:15 uur Ontvangst bij AFAS&lt;/li&gt;    &lt;li&gt;18:15 - 18:45 uur &lt;b&gt;Welkom &lt;/b&gt;Keynote Amit Chatterjee - Host&lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;li&gt;18:45 - 20:15 uur&lt;b&gt;Visual Studio 2010, Interactieve sessie&lt;/b&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;ul&gt;   &lt;ul&gt;     &lt;li&gt;Web development&lt;/li&gt;      &lt;li&gt;Office development / SharePoint&lt;/li&gt;      &lt;li&gt;Windows Azure&lt;/li&gt;      &lt;li&gt;ALM&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;Sprekers Anko Duizer, Alex Thissen, Marcel de Vries, Wouter van Vugt&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;20:15 - 21:30 uur &lt;b&gt;Borrel - Interviews met communities&lt;/b&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We hopen dat jullie allemaal langskomen bij dit event!&lt;/p&gt;  &lt;p&gt;Je kunt je aanmelden voor de avond op twee manieren:&lt;/p&gt;  &lt;p&gt;1. Aanmelden voor het bijwonen van dit event in Leusden: &lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032448067&amp;amp;Culture=nl-NL"&gt;https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032448067&amp;amp;Culture=nl-NL&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2. Aanmelden voor het online event: &lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032448182&amp;amp;Culture=nl-NL"&gt;https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032448182&amp;amp;Culture=nl-NL&lt;/a&gt;&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1023" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1002.aspx">Visual Studio Team System</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1010.aspx">Events</category></item><item><title>Surface Lanparty bij Sevensteps</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/03/12/1021.aspx</link><pubDate>Fri, 12 Mar 2010 09:23:58 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1021</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1021.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1021</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1021.aspx</wfw:comment><description>&lt;p&gt;Eind maart vinden weer de &lt;a href="http://www.devdays.nl/" target="_blank"&gt;DevDays&lt;/a&gt; plaats. Voor mij is dat 2 dagen lang met vakgenoten bijpraten en mijn kennis bijspijkeren over alles wat er gebeurd op het gebied van .net ontwikkelingen. En net als voorgaande jaren kun je 's avonds naar de &lt;a href="http://www.devdays.nl/GeekNight.aspx?pid=71&amp;amp;lang=nl" target="_blank"&gt;Geek Night&lt;/a&gt;. Het idee achter de Geek Night is dat hier een platform geboden wordt waarin onderwerpen de revue passeren die je niet zo gauw in een reguliere sessie ziet. De nadruk hier ligt op het 'fun' gedeelte van de technologie waar we dagelijks mee werken. En dan bedoel ik niet de fun die je normaal ondergaat als je bezig bent met de nieuwste release van &lt;a href="http://www.asp.net/(S(d35rmemuuono1wvm1gsp2n45))/mvc/" target="_blank"&gt;het MVC pattern voor ASP.Net&lt;/a&gt; (hoewel dat ook leuk is!). Nee, met fun praten we over toepassingen die je niet zo gauw tegen komt in je dagelijkse werkzaamheden. Denk bijvoorbeeld aan het aansturen van robots met .net. Je weet wel, de dingen waar je je vroeger als hobbyist mee bezig hield.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sevensteps.nl" target="_blank"&gt;Sevensteps&lt;/a&gt; had een leuk idee. Zou het niet aardig zijn om een applicatie te maken die gebruikt kan worden tijdens de keynote zodat het publiek enigzins kan participeren? Op zich kun je daar wel wat voor verzinnen maar aangezien het een applicatie voor de Geek Night moest zijn, moest het een hoog gadget gehalte hebben. Dus kwam de keuze al gauw op het maken van een Microsoft Surface applicate in combinatie met Twitter. En belangrijker: het zou nog mooier zijn als die applicatie een community effort zou zijn.&lt;/p&gt;  &lt;p&gt;Het resultaat was dat Sevensteps op donderdag 11 maart een Lanparty organiseerde. Op die dagen kwam een groep enthousiaste ontwikkelaars bij elkaar in Amersfoort om samen, in een dag, een geweldige applicatie voor de Geek Night te maken. In die ene dag zou alles wat te maken heeft met software ontwikkeling de revue passeren:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;brainstormen over functionaliteit&lt;/li&gt;    &lt;li&gt;bedenken van design&lt;/li&gt;    &lt;li&gt;opdelen van het team in werkgroepen&lt;/li&gt;    &lt;li&gt;scrum sessies (sprints van 90 minuten!)&lt;/li&gt;    &lt;li&gt;ontwikkelen van de software&lt;/li&gt;    &lt;li&gt;'tekenen' van de User Experience&lt;/li&gt;    &lt;li&gt;testen&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Met andere woorden: alles wat we de hele dag al doen maar nu in 1 dag. Om eerlijk te zijn vond ik het hele plan nogal ambitieus. Het idee voor de applicatie bestond alleen maar in hele vage vorm, en dan zouden wij in 1 dag een geheel systeem kunnen bouwen? Maar goed, ook als het niet zou lukken zou het een leuke dag worden waar iedereen als het goed is wat van kon leren.&lt;/p&gt;  &lt;p&gt;Dus vol goede moed stond in om half 9 in Amersfoort bij Sevensteps voor de deur. In het half uur dat volgde kwam iedereen binnen en rond 9.15 waren er 12 mensen aanwezig. Na een korte inleiding door Sevensteps over het idee, de manier van werken en een korte introductie in het Model View Viewmodel pattern verzamelden we ons rond een whiteboard en begonnen te brainstormen.&lt;/p&gt;  &lt;p&gt;Al snel ontstonden er een aantal goede maar ook minder goede ideeen, en daar werden leuke discussies over gehouden. Vervolgens werden er werkgroepjes van 2 a 3 personen gevormd die elkaar goed aanvulden qua kennis en interesse. Iedere 90 minuten zou ieder team iets bouwen of designen en na die 90 minuten werd er een scrum gehouden om te kijken wat er gedaan was, wat er nog moest gebeuren en waar de eventuele problemen lagen.&lt;/p&gt;  &lt;p&gt;Nou heb ik veel ervaring in het maken van Surface systemen maar dat goldt uiteraard niet voor iedereen. De eerste horde die genomen moest worden was dat men de Surface SDK op de machine moest krijgen. Tegen de tijd dat iedereen aan de gang kon gaan liep het tegen 11 uur. En bedenk dat de meeste mensen nog nooit voor Surface ontwikkeled hadden. Op dat moment was ik er van overtuigd dat het allemaal niet zou gaan lukken.&lt;/p&gt;  &lt;p&gt;Maar tot mijn verbazing ging het na de eerste sprint opeens erg snel. Het team pakte het goed op, leerde veel van elkaar en werden steeds enthousiaster. Er ontstonden nieuwe ideeen en&amp;#160; verfijningen van het ontwerp en iedereen hielp elkaar waar het kon. Uiteraard speelde de goede voorbereiding van Sevensteps een belangrijke rol: het netwerk deed het prima, SVN was goed ingeregeld dus niemand hoefde zich om dat soort randvoorwaarden zorgen te maken.&lt;/p&gt;  &lt;p&gt;Na iedere sprint zagen we de software steeds beter worden. De manier van werken (MVVM) zorgde er voor dat men in staat was om snel code te produceren en die over te dragen aan de designers die er dan iets moois van gingen maken. De sfeer werd eigenlijk alleen maar beter en beter wat er voor zorgde dat de productiviteit enorm hoog was.&lt;/p&gt;  &lt;p&gt;Na de pizza (met dank aan Microsoft) kwamen we op het punt dat alles samengevoegd moest gaan worden. En tot onze grote verassing stond er rond 10 uur 's avonds opeens een werkend systeem op de Surface unit. &lt;/p&gt;  &lt;p&gt;De les die ik hiervan geleerd heb is dat als je een enorm gemotiveerd team hebt, en je zorgt dat de randvoorwaarden (goede machines, goede omgeving, goede sfeer) voor elkaar zijn, een groep ontwikkelaars in staat is om heel snel hele mooie dingen op te leveren. Nu moet ik nog kijken hoe ik dat kan doorvoeren bij mijn klanten.&lt;/p&gt;  &lt;p&gt;Al met al was het een enorm leuke en leerzame dag, waarbij ik een aantal mensen die ik eigenlijk alleen via Twitter sprak beter heb leren kennen. Wat mij betreft: volgend jaar weer!&lt;/p&gt;  &lt;p&gt;PS Nee. Ik ben niet vergeten om te beschrijven wat voor systeem we gemaakt hebben. Als je dat wilt zien zul je toch echt naar de Geek Night op DevDays moeten komen. Je kunt ook op twitter zoeken naar de &lt;a href="http://search.twitter.com/search?q=%23s7lp+OR+%237slp" target="_blank"&gt;hashtag #7slp of #s7lp&lt;/a&gt; (die laatste was een typfout maar werd wel gebruikt) om de voortgang van de dag te zien. &lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1021" width="1" height="1"&gt;</description></item><item><title>Terug naar de blogosphere.</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2010/03/07/1020.aspx</link><pubDate>Sun, 07 Mar 2010 11:21:01 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1020</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1020.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1020</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1020.aspx</wfw:comment><description>&lt;p&gt;Ok. Ik weet het. We hebben het allemaal druk. Het is crisis/depressie/chaos of hoe je de markt ook wil noemen en dat betekent dat we allemaal een stapje harder moeten lopen. Is dat een reden om niet meer te bloggen? Nou uhm nee. Eigenlijk niet. Maar tel daar bij op dat ik de afgelopen maanden bezig geweest ben met het oprichten van een nieuw bedrijf, weken heb gemaakt van over de 130 uur (ik weet het, dat betekent meerdere nachten niet slapen maar werken) en je begrijpt dat mijn focus een tijdje ergens anders heeft gelegen.&lt;/p&gt;  &lt;p&gt;Maar die tijd is voorbij: ik ben weer druk bezig om orde in de chaos te scheppen en een van de gevolgen is dat ik weer veel meer tijd heb gekregen om zaken op te pakken die ik belangrijk vindt. Naast tijd voor mijn gezin houdt dat ook in dat ik meer tijd heb voor dotNed, de Surface user group en uiteraard het schrijven van artikelen, blogposts en het houden van lezingen. Goh, wat heb ik dat gemist.&lt;/p&gt;  &lt;p&gt;Dus.. ik ben weer terug en je hoort heel gauw nog veel meer van me!&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1020" width="1" height="1"&gt;</description></item><item><title>CodeCamp 2009: Sessies en OpenSpace</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/11/07/1014.aspx</link><pubDate>Sat, 07 Nov 2009 09:37:37 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1014</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1014.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1014</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1014.aspx</wfw:comment><description>&lt;p&gt;Als eerste: de sessies voor de CodeCamp 2009 zijn bekend en staan online op &lt;a href="http://www.codecamp.nl"&gt;http://www.codecamp.nl&lt;/a&gt; We denken dat het een erg interessante mix van sessies is, met genoeg sessies voor iedereen om een aantal interessante onderwerpen voor iedereen. De agenda ziet er nu als volgt uit:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Tijdslot&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Track A&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Track B&lt;/strong&gt;&lt;/td&gt;        &lt;td&gt;&lt;strong&gt;Track C&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;09:30 - 10:45&lt;/td&gt;        &lt;td&gt;Around .net framework 4.0 in an hour (Ronald Guijt)&lt;/td&gt;        &lt;td&gt;ASP.Net - MVC 2.0 (Sander Gerz)&lt;/td&gt;        &lt;td&gt;Windows Mobile en het werken met data (Arjan van Huizen)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;11:00 - 12:15&lt;/td&gt;        &lt;td&gt;ADO.NET EF 4.0 (Kurt Claeys)&lt;/td&gt;        &lt;td&gt;SharePoint Nightmares (Marianne van Wanrooij)&lt;/td&gt;        &lt;td&gt;iPhone development met jQTouch (Maurice de Beijer)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;13:15 - 14.30&lt;/td&gt;        &lt;td&gt;VSTO 2010 met Office 2010 (Hassan Fadili)&lt;/td&gt;        &lt;td&gt;Modulaire Silverlight apps met Prism (Timmy Kokke)&lt;/td&gt;        &lt;td&gt;Microsoft Surface Development (Freena Eijffinger &amp;amp; Dennis Vroegop)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;14:45 - 16:00&lt;/td&gt;        &lt;td&gt;VSTS 2010 (Pieter de Bruijn)&lt;/td&gt;        &lt;td&gt;Windows Identity Foundation (Michiel van Otegem)&lt;/td&gt;        &lt;td&gt;SQL Azure (Marcel Meijer)&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;Naast deze sessies hebben we ook nog de OpenSpace sessies. Daar hebben we geen agenda voor maar dat ligt nu eenmaal in de aard van een OpenSpace gebeuren. In het kort komt het neer op het volgende: als je iets hebt waar je graag met een aantal mensen over wilt discussieren, schrijf je dat 's ochtends op een flip-over. Mochten mensen dat interessant vinden, dan kunnen ze een stem uitbrengen op dat onderwerp. In de lunchtijd (van 12:15 - 13:15) is dan de keuze aan de mensen waar ze heen gaan en aan welke discussie ze mee willen gaan doen. Heeft jouw sessie genoeg stemmen dan komen de mensen vanzelf wel naar je toe, zo niet: dan is je sessie blijkbaar niet interessant voor een grote groep. Het idee is dat we een aantal van deze sessies tegelijkertijd hebben zodat mensen kunnen kiezen wat ze doen. De inhoud van de lunch sessies laten we dus volledig aan de bezoekers over! &lt;/p&gt;  &lt;p&gt;Denk eens na over sessies of onderwerpen en discussieer mee met je mede-ontwikkelaars over jouw favoriete onderwerp!&lt;/p&gt;  &lt;p&gt;Ik kan haast niet wachten tot het 21 november is..&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1014" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1001.aspx">dotNed</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1010.aspx">Events</category></item><item><title>CodeCamp 2009: Call For Speakers</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/10/27/1012.aspx</link><pubDate>Tue, 27 Oct 2009 08:41:00 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1012</guid><dc:creator>dvroegop</dc:creator><slash:comments>1</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1012.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1012</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1012.aspx</wfw:comment><description>&lt;P&gt;Op 21 november 2009 organiseren de SDN, de dotNED User Group en VBcentral.nl samen de derde Nederlandse Code Camp. Een unieke dag, voortkomend uit een unieke samenwerking. Kenmerkend aan deze dag is, dat het een evenement is dóór ontwikkelaars en vóór ontwikkelaars!&lt;/P&gt;
&lt;P&gt;We zijn op zoek naar collega ontwikkelaars die het leuk vinden om ook een sessie voor hun rekening te nemen. Er is ruimte voor de meer traditionele sessies, maar bijvoorbeeld ook voor Chalk &amp;amp; Talk sessies. In principe is zijn de mogelijke onderwerpen zeer divers en worden door ons op voorhand niet beperkt. Ben jij geïnteresseerd om ook een sessie te doen? Laat het ons weten! Ook als je geen of nog niet zoveel sprekerservaring hebt ben je meer dan welkom. Indien je dat wilt willen we je hier best mee helpen.&lt;/P&gt;
&lt;P&gt;Het evenement vindt plaats in Rotterdam en meer informatie kun je vinden op de Code Camp website:&lt;A href="http://www.codecamp.nl/"&gt;www.codecamp.nl&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;We zien graag jouw sessievoorstel tegemoet! Stuur deze zo snel mogelijk naar: &lt;A href="mailto:andre@obelink.com"&gt;andre@obelink.com&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Een lijstje van onderwerpen waar deelnemers ondermeer om vragen:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Architectuur/Design patterns 
&lt;LI&gt;Frameworks 
&lt;LI&gt;Surface 
&lt;LI&gt;.NET 4/3.5 
&lt;LI&gt;Visual Studio 2010 
&lt;LI&gt;VSTS 
&lt;LI&gt;Open Source 
&lt;LI&gt;SharePoint 
&lt;LI&gt;ASP.NET/MVC/Web development/Silverlight 
&lt;LI&gt;Windows 7 
&lt;LI&gt;iPhone 
&lt;LI&gt;DNN 
&lt;LI&gt;VSTO 
&lt;LI&gt;LINQ 
&lt;LI&gt;SQL Server 2008 
&lt;LI&gt;Geneva 
&lt;LI&gt;BizTalk 
&lt;LI&gt;Windows Presentation Foundation 
&lt;LI&gt;Windows Communication Foundation 
&lt;LI&gt;Windows Workflow Foundation &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1012" width="1" height="1"&gt;</description></item><item><title>OpenCoffee was leuk!</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/09/05/1004.aspx</link><pubDate>Sat, 05 Sep 2009 07:28:02 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1004</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1004.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1004</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1004.aspx</wfw:comment><description>&lt;p&gt;Op vrijdag 4 september hadden we bij dotNed de tweede OpenCoffee. Dit keer was de avond gesponsort door &lt;a title="Website QDelft" href="http://www.qdelft.nl" target="_blank"&gt;QDelft&lt;/a&gt;. De opkomst was beter dan verwacht: we hadden ongeveer twee keer zoveel mensen dan we eigenlijk verwacht hadden.&lt;/p&gt;  &lt;p&gt;Veel mensen die aanwezig waren kenden elkaar eigenlijk alleen via het online circuit, en dan met name via Twitter. Het was leuk om te zien hoe dat werkte: je zag mensen eerst voorzichtig aftasten ("hee, uhm, ben jij niet.") maar al snel werden de gespreken die eerst via Twitter verliepen doorgezet onder het genot van een biertje en een hapje. QDelft had de catering prima voor elkaar, er was genoeg te eten en te drinken voor iedereen, iets wat de sfeer enorm positief veranderde. &lt;/p&gt;  &lt;p&gt;De gesprekken gingen over allerlei verschillende onderwerpen. Uiteraard werd er veel over .net gesproken, maar ook andere onderwerpen passeerden de revue. Er zijn een hoop nieuwe contacten gelegd en oude contacten werden verstevigd. Het was dus een leuke manier om te netwerken.&lt;/p&gt;  &lt;p&gt;Wat mij betreft houden we binnenkort graag weer zo'n avond!&lt;/p&gt;  &lt;p&gt;Met dank aan &lt;a title="Twitter pagina van Mendelt" href="http://twitter.com/mendelt" target="_blank"&gt;Mendelt&lt;/a&gt; (met een passie voor Mono, dus mocht je een Mono expert nodig hebben moet je bij hem zijn :-) ) voor zijn inzet en uiteraard aan &lt;a title="QDelft" href="http://www.qdelft.nl" target="_blank"&gt;QDelft&lt;/a&gt; voor het hosten van deze avond!&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1004" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1001.aspx">dotNed</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1010.aspx">Events</category></item><item><title>OpenCoffee op 4 september</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/08/21/1001.aspx</link><pubDate>Fri, 21 Aug 2009 11:21:00 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:1001</guid><dc:creator>dvroegop</dc:creator><slash:comments>2</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/1001.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=1001</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/1001.aspx</wfw:comment><description>&lt;P&gt;Het is weer eens tijd voor een OpenCoffee / OpenBeer event bij dotNed. De meeste mensen zijn weer terug van vakantie, een mooie gelegenheid om bij elkaar te komen en te praten met je mede ontwikkelaars!&lt;/P&gt;
&lt;P&gt;Op een OpenCoffee zijn er geen presentaties, geen workshops en geen chalk 'n talks. Wel zijn er ontwikkelaars zoals jij, die graag over hun werk praten en ideeen willen uitwisselen! &lt;/P&gt;
&lt;P&gt;Deze OpenCoffee (uiteraard gratis, dit keer gesponsort door &lt;A href="http://www.qdelft.nl" target=_blank&gt;QDelft&lt;/A&gt;) vindt plaats op 4 september te Delft. Een routebeschrijving vind je &lt;A href="http://www.qdelft.nl/nl/57/contact/routebeschrijving.html" target=_blank&gt;hier&lt;/A&gt;. Aanmelden hoeft niet, maar we vinden het wel fijn als je even laat weten dat je langs komt. Dit in verband met de catering. Je bent van harte welkom vanaf 5 uur!&lt;/P&gt;
&lt;P&gt;Als je langs wilt komen stuur dan even een berichtje. Dat kan naar mij (&lt;A href="mailto:dennis@dotned.nl"&gt;dennis@dotned.nl&lt;/A&gt; of twitter &lt;A href="http://twitter.com/dvroegop" target=_blank&gt;@dvroegop&lt;/A&gt;) of naar de initiatiefnemer van deze OpenCoffee Mendelt Siebenga (twitter &lt;A href="http://twitter.com/mendelt" target=_blank&gt;@mendelt&lt;/A&gt;) &lt;/P&gt;
&lt;P&gt;We zien je graag op de 4e!&lt;/P&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=1001" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1001.aspx">dotNed</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1010.aspx">Events</category></item><item><title>Geslaagde launch van de Surface Gebruikers groep Nederland</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/07/01/998.aspx</link><pubDate>Wed, 01 Jul 2009 14:48:40 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:998</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/998.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=998</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/998.aspx</wfw:comment><description>&lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/GeslaagdelaunchvandeSurfaceGebruikersgro_EC5E/Logo_Sugar.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Logo_Sugar" border="0" alt="Logo_Sugar" src="http://community.dotned.nl/blogs/dvroegop/GeslaagdelaunchvandeSurfaceGebruikersgro_EC5E/Logo_Sugar_thumb.png" width="154" height="154" /&gt;&lt;/a&gt; Donderdag 25 juni stond de dotNed meeting in het teken van Microsoft Surface. We hebben de avond benut om de nieuwe gebruikersgroep te lanceren, je vindt hier meer informatie over op &lt;a href="http://surface.dotned.nl"&gt;http://surface.dotned.nl&lt;/a&gt; Sevensteps waren zo vriendelijk om een video impressie te maken, deze kan je &lt;a title="Video impressie van Surface GG bijeenkomst" href="http://www.youtube.com/watch?v=IlWIhv4JNpA" target="_blank"&gt;hier bekijken&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Wat mij betreft houden we gauw weer zo'n avond!&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=998" width="1" height="1"&gt;</description><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1001.aspx">dotNed</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1010.aspx">Events</category><category domain="http://community.dotned.nl/blogs/dennis_blog/archive/category/1020.aspx">Surface</category></item><item><title>Surface, design challenges</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/06/30/997.aspx</link><pubDate>Tue, 30 Jun 2009 08:45:26 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:997</guid><dc:creator>dvroegop</dc:creator><slash:comments>0</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/997.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=997</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/997.aspx</wfw:comment><description>&lt;p&gt;Surface is cool. Iedereen die er naar gekeken heeft is dat wel met me eens. Hoewel de hardware op het eerste gezicht niet echt indrukwekkend is (een tafel met een PC erin, dat is toch niets nieuws?) zijn er behoorlijk wat geavanceerde technieken toegepast. Niet voor niets heeft Microsoft meer dan 100 patenten aangevraagd op toegepaste ideeen in de tafel. De meeste daarvan hebben te maken met het projectie en vision gedeelte, ik neem aan dat er heel wat drempels overwonnen zijn om dit allemaal voor elkaar te krijgen.&lt;/p&gt;  &lt;p&gt;Het programmeren voor Surface is makkelijk. Nou ja, makkelijk voor mensen die ervaring hebben met WPF. Ook XNA kenners kunnen goed aan de slag met Surface maar ik denk dat 90% van de developers met de WPF versie aan de gang gaan.&lt;/p&gt;  &lt;p&gt;Als ik een demo geef aan mensen zegt iedereen dat het zo eenvoudig is om software te schrijven voor Surface. WPF, wat extra controls en meer heb je niet nodig. Iedereen kan het! We moeten echter niet vergeten dat 'die paar extra controls' heel wat manjaar werk in zich hebben: het is vaak zo dat hoe makkelijker iets in het gebruik is, hoe moeilijker het is geweest om het te bedenken en te bouwen.&lt;/p&gt;  &lt;p&gt;Maar goed,&amp;#160; hoewel de hardware dus best indrukwekkend is en de SDK goed in elkaar zit, is er eigenlijk niets dat ons tegenhoudt om hele mooie applicaties te schrijven voor Surface. Toch? Nou. er is nog een klein dingetje dat we moeten doen: het verzinnen van een goede applicatie voor Surface.&lt;/p&gt;  &lt;p&gt;En daar schuilt het grote probleem.&lt;/p&gt;  &lt;p&gt;Surface is een heel nieuw platform. Niet qua hardware en zeker niet qua software, maar wel voor wat betreft het gebruik.&lt;/p&gt;  &lt;p&gt;Surface is een platform voor de Natural User Interface (NUI). Dit is iets heel anders dan de Graphical User Interface (GUI) die we gewend zijn. Ik durf zelf te zeggen dat de overgang van GUI naar NUI net zo groot, dan niet groter is dan de overgang van Command Line Interface (CLI) naar GUI! En dat was al geen makkelijke stap!&lt;/p&gt;  &lt;p&gt;In een GUI maken we gebruik van metaforen. We maken afbeeldingen die iets voorstellen in de echte wereld. Denk aan een icoontje van een prullebak om aan te geven dat we iets weg willen gooien. Een tekening van een papiertje zal wel iets met afdrukken te maken hebben, en zo voorts. Ook het gebruik van de mousepointer, menus, windows en dergelijke zijn allemaal metaforen voor dingen uit het echte leven. De bedoeling is dat de gebruikers die zaken herkennen en snappen wat de bedoeling is. Dat dit niet altijd zo werkt wordt wel bewezen door de enorme hoeveelheid trainingen en documentatie die applicaties nodig hebben om duidelijke te maken wat de gebruiker met de software kan doen. Blijkbaar is voor veel gebruikers de mentale stap van abstract icoontje naar 'real-life' toch te groot! Voor de duidelijkheid: ik heb het niet over mensen zoals jij en ik: wij zijn dit gewend en we weten niet beter. Ik praat hier over de gemiddelde gebruiker die slechts af en toe achter een computer zit. Voor die mensen is het allemaal erg ingewikkeld!&lt;/p&gt;  &lt;p&gt;Een NUI gaat een stap verder. In plaats van een abstracte afbeelding maken we gebruik van echte, fysieke objecten. In plaats van gegevens op een formulier in te vullen met je naam en wachtwoord om in te loggen, leg je je visitekaartje neer op de tafel. De machine weet nu wie je bent, je hoeft verder geen actie te ondernemen. In plaats van iets te selecteren en dan op een knopje met een prullebak te drukken, sleep je een foto op het scherm naar een prullebak: zelfs mijn dochter van 6 snapt dat. &lt;/p&gt;  &lt;p&gt;De uitdagingen voor Surface zijn echter groter.&lt;/p&gt;  &lt;p&gt;In Surface kennen we in principe geen CurrentUser. Een applicatie kan gelijkertijd door meerder mensen bedient worden. Dat betekent dat als we een systeem schrijven we bijvoorbeeld geen acties kunenn maken die de state van de gehele applicatie veranderd. Een voorbeeld verduidelijkt dit:&lt;/p&gt;  &lt;p&gt;Stel, we maken een vingerverf applicatie. Op het scherm kunnen we een kaartje neerleggen met een kleur erop: op het moment dat bijvoorbeeld een groen kaartje neergelegd wordt worden alle vingerbewegingen op het scherm neergezet als groene strepen. Halen we het groene kaartje weg en vervangen we deze door een rode, kun je met rood verfen. Hartstikke leuk natuurlijk, maar wat als jij en ik nu samen aan onze versie van Mona Lisa bezig zijn? Ik wil het haar zwart maken, maar net op het moment dat ik met mijn vingers dat begin in te kleuren vervang jij het zwarte kaartje door eeen witte (want jij wilt de ogen inkleuren). Op datmoment kan ik niets meer doen: ik moet wachten tot jij klaar bent met wit. &lt;/p&gt;  &lt;p&gt;Daarnaast zijn wij, als traditionele programmeurs, gewend aan een aantal standaard metaforen. Zo zie je in veel applicaties een of andere vorm van een 'save' button om de huidige status op te slaan. Als je hier over nadenkt is dat best vreemd: in het echte leven doen we dat ook niet. Als ik iets op een papiertje schrijf hoef ik dat niet op te slaan. Dus in een NUI zou ik dat ook niet moeten doen!&lt;/p&gt;  &lt;p&gt;Nu is het niet zo moeilijk om software zo te schrijven dat de state altijd opgeslagen wordt. Maar wat als je nu de state voor meerdere cases wilt opslaan? In onze vingerverf applicatie wil ik een tekening kunnen maken, maar ik wil niet dat jouw tekening de mijne overschrijft (andersom vind ik persoonlijk niet zo erg :-) ) Hoe lossen we dat nou op? Dat kunnen we bijvoorbeeld doen door iedereen een object te geven (bijvoorbeeld een pasfoto). Op het moment dat die pasfoto op het systeem ligt weet Surface voor welke gebruiker deze tekening is. Als ik mijn foto weg haal en jij legt de jouwe neer, zal mijn kunstwerk opgeslagen worden en komt de jouwe tevoorschijn (indien het tekenen een groepsactiviteit is kunnen we een groepsfoto plaatsen.) Geen 'save' knop meer: altijd toegang tot mijn werk en ik heb geen toegang tot jouw werk. Precies zoals een normale gebruiker verwacht.&lt;/p&gt;  &lt;p&gt;Surface is een tafel. Het leuke van een tafel is dat mensen er om heen gaan staan. Het nadeel is dus wel dat je geen applicaties kunt maken die een duidelijke onder- en bovenkant hebben. Immers, als er tekst op het scherm staat is dat voor een persoon goed te lezen, maar de andere gebruikers kunnen daar niets mee (nou ja, ze kunnen het op z'n kop lezen maar handig is dat niet). Je moet dus rekening houden met dit aspect. Niet eenvoudig!&lt;/p&gt;  &lt;p&gt;Ik denk dat veel ontwikkelaars in het begin dit soort fouten gaan maken. Ook ik maak me daar nog steeds schuldig aan. Ik heb op zich een goede oplossing: mijn dochter van 6 is een geweldige beta tester. Hoewel ze niet begrijpt wat de systemen doen,&amp;#160; kan ze er wel mee overweg. De User Interface heeft geen geheimen voor haar. Als die geheimen er wel zijn, heb ik mijn werk niet goed gedaan.&lt;/p&gt;  &lt;p&gt;Ik hoef nu alleen nog maar even een killer applicatie voor Surface bedenken..&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=997" width="1" height="1"&gt;</description></item><item><title>Introducing: Surface User Group Netherlands</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/2009/06/25/994.aspx</link><pubDate>Thu, 25 Jun 2009 07:40:00 GMT</pubDate><guid isPermaLink="false">c31f1c9d-3d74-4570-b753-7c0d5aab146d:994</guid><dc:creator>dvroegop</dc:creator><slash:comments>1</slash:comments><comments>http://community.dotned.nl/blogs/dennis_blog/comments/994.aspx</comments><wfw:commentRss>http://community.dotned.nl/blogs/dennis_blog/commentrss.aspx?PostID=994</wfw:commentRss><wfw:comment>http://community.dotned.nl/blogs/rsscomments/994.aspx</wfw:comment><description>&lt;p&gt;&lt;a title="Surface Gebruikers Groep Nederland" href="http://surface.dotned.nl" target="_blank"&gt;&lt;img style="border-right-width: 0px; margin: 5px 15px 15px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Logo Surface UG" border="0" alt="Logo Surface UG" align="left" src="http://community.dotned.nl/blogs/dvroegop/IntroducingSurfaceUserGroupNetherlands_8FAC/web_750x750.png" width="244" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Met gepaste trots introduceren we een nieuw onderdeel van dotNed: de Surface User Group Nederland. We hebben een nieuwe &lt;a href="http://surface.dotned.nl/" target="_blank"&gt;Surface User Group Website&lt;/a&gt; (nog in ontwikkeling, maar de homepage staat er), een nieuw logo en veel nieuwe ideeen! &lt;/p&gt;  &lt;p&gt;We denken dat het introduceren van een nieuwe GG (gebruikersgroep, voor het geval je de afkorting niet kent) een aantal vragen opwerpt:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Waarom een nieuwe gebruikersgroep? &lt;/li&gt;    &lt;li&gt;Waarom kan dit niet gewoon onder de vlag van dotNed? &lt;/li&gt;    &lt;li&gt;Wat is uberhaupt Surface? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In deze blogpost zullen we uitleggen wat het idee is en wat we van plan zijn met de nieuwe GG. &lt;/p&gt;  &lt;p&gt;Indien je niet weet wat Microsoft Surface is, raad ik je aan even naar de &lt;a title="MS Surface Website" href="http://www.microsoft.com/surface" target="_blank"&gt;officiele Microsoft Surface Website&lt;/a&gt; te gaan. Daar kun je een voorproefje krijgen van wat het platform biedt.&lt;/p&gt;  &lt;p&gt;We denken dat Surface een concept is dat een revolutie in computer gebruik teweeg kan brengen. Het platform is dusdanig vernieuwend dat mensen niet goed weten wat het is en wat ze er mee kunnen. In tegenstelling tot het .net framework snappen veel mensen het concept van Surface niet helemaal. &lt;/p&gt;  &lt;p&gt;In de oprichtingsnotulen van dotNed staat dat het doel van dotNed is "&lt;em&gt;het promoten van het .net framework en het verspreiden van kennis hierover"&lt;/em&gt;. Nu is het promoten van het .net framework niet echt meer nodig: iedereen weet ondertussen wel wat het is en waarom het gebruik van .net een goed idee is. De laatste jaren houden we ons dus voornamelijk bezig met het verspreiden van de kennis over .net. Dat doen we door maandelijks een gratis bijeenkomst te organiseren, aanwezig te zijn op de diverse grote events en door middel van onze blogs.&lt;/p&gt;  &lt;p&gt;Voor Surface ligt dit anders. Ook hier geloof ik dat het belangrijk is om de uitgangspunten van dotNed uit te dragen, namelijk het promoten van het platform en het uitwisselen van kennis hiervan, maar het nut van Surface is nog niet bij iedereen duidelijk. We willen ons bij de Surface GG gaan richten op het beantwoorden van de onderstaande 3 vragen:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.dotned.nl/blogs/dvroegop/IntroducingSurfaceUserGroupNetherlands_8FAC/WatWaaromHoe.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="WatWaaromHoe" border="0" alt="WatWaaromHoe" src="http://community.dotned.nl/blogs/dvroegop/IntroducingSurfaceUserGroupNetherlands_8FAC/WatWaaromHoe_thumb.png" width="513" height="480" /&gt;&lt;/a&gt;"Wat" gaat in op de vraag wat Surface nou precies is. Wat is het voor machine, wat is het concept erachter, hoe bestel ik er een, wat is de techniek erachter. "Waarom" is meer conceptueel: waarom zou ik als organisatie zo'n machine aanschaffen? Waarom is dat handig voor mij? Wat kan ik er allemaal mee dat mij een voorsprong op mijn concurrenten geeft? Met andere woorden: met het beantwoorden van de "waarom" vraag gaan we in het conceptuele niveau van Surface. &lt;/p&gt;  &lt;p&gt;"Hoe" is meer technisch: hoe maak ik nu applicaties op Surface? Hoe voldoe ik aan de guidelines van Microsoft? Hoe plaats ik een ElementMenu in mijn ScatterViewItem? (Mocht je niet weten wat een ElementMenu of een ScatterViewItem is, dan geven we daar natuurlijk eerst uitleg over :-) ) Naast de technische aspecten zullen we ook diep ingaan op vraagstukken op het gebied van User Experience. Het concept van Surface stelt hele andere eisen aan de user interface dan een Windows of Web applicatie. &lt;/p&gt;  &lt;p&gt;Je ziet dat we met deze 3 vragen verschillende doelgroepen bedienen. Met de "waarom" vraag helpen we de decisionmakers, met de "hoe" vraag helpen we de ontwikkelaars op dit platform. De "wat" vraag is uiteraard bedoelt voor iedereen die iets meer over Surface wil weten.&lt;/p&gt;  &lt;p&gt;Hoe bereiken we nu dat we de goede antwoorden geven? We hebben daarvoor een paar mogelijkheden:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Blog posts. Dit is behoorlijk eenrichtingsverkeer, maar we kunnen daardoor wel veel informatie bij jullie kwijt &lt;/li&gt;    &lt;li&gt;Een forum. Dit zal de plek worden waar mensen vragen kunnen stellen &lt;em&gt;en &lt;/em&gt;beantwoorden. Wij van dotNed zullen hier een actieve rol in spelen. &lt;/li&gt;    &lt;li&gt;Bijeenkomsten. We zullen regelmatig bijeenkomsten organiseren, bij voorkeur bij bedrijven die een Surface Unit hebben staan, om daar hands-on ideeen op te doen. Dit is uiteraard de beste manier om de Surface Unit van dicht bij te zien en er mee te werken. &lt;/li&gt;    &lt;li&gt;Lezingen geven. Om de wat/waarom vragen te beantwoorden zijn we altijd bereid om naar organisaties toe te gaan om ze daar uit te leggen wat Surface is en wat het voor kun kan doen (verzoeken even mailen naar &lt;a href="mailto:dennis@dotned.nl"&gt;dennis@dotned.nl&lt;/a&gt; ) Uiteraard geldt dit niet alleen voor commerciele organisaties maar ook op het gebied van onderwijs en non-profit organisaties &lt;/li&gt;    &lt;li&gt;Acte de presence geven op events van andere partijen. Denk aan een DevDays, SDN events en dergelijke. &lt;/li&gt;    &lt;li&gt;Delen van code libaries, met daarin 'best practices' voor het ontwikkelen op Surface. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;De mensen achter de Surface GG zijn allemaal early adopters van het platform. We hebben de trainingen gevolgd en hebben reeds een aantal applicaties opgeleverd op Surface bij onze klanten. We mogen dan ook wel stellen dat het kennis niveau behoorlijk hoog is, maar we willen altijd meer leren en weten wat er allemaal gebeurd op dit platform! De Surface GG wordt momenteel aangestuurd door drie personen:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Bart Roozendaal (&lt;a href="mailto:bart@dotned.nl"&gt;bart@dotned.nl&lt;/a&gt;) , &lt;a title="Sevensteps" href="http://www.sevensteps.com/" target="_blank"&gt;Sevensteps&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Bas Zweeris (&lt;a href="mailto:bas@dotned.nl"&gt;bas@dotned.nl&lt;/a&gt;) , &lt;a title="Cap Gemini" href="http://www.capgemini.com" target="_blank"&gt;Capgemini&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Dennis Vroegop (&lt;a href="mailto:dennis@dotned.nl"&gt;dennis@dotned.nl&lt;/a&gt;), &lt;a title="Detrio" href="http://www.detrio.nl" target="_blank"&gt;Detrio&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Mocht je dus bij een bedrijf werken die een Surface heeft, of worstelt met de vraag of ze er een (of meerderer!) aan moeten gaan schaffen, neem dan even contact op met ons zodat we kunnen kijken wat we voor elkaar kunnen betekenen!&lt;/p&gt;  &lt;p&gt;We zijn een community. Een community bestaat bij de gratie van de communityleden. Wij hebben veel ideeen, maar die kunnen pas tot leven komen als jullie mee denken en actief meedoen. Wat dat betreft is geen enkel verschil met dotNed, we zijn er voor &lt;em&gt;en&lt;/em&gt; door jullie! We willen graag jullie ideeen horen. Dat kan op verschillende manieren:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Kom naar de bijeenkomsten en laat van je horen &lt;/li&gt;    &lt;li&gt;Via Twitter ben ik te bereiken op &lt;a href="http://www.twitter.com/dvroegop"&gt;http://www.twitter.com/dvroegop&lt;/a&gt; (of in een Twitterclient @dvroegop) &lt;/li&gt;    &lt;li&gt;Email: &lt;a href="mailto:dennis@dotned.nl"&gt;dennis@dotned.nl&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Of laat een reactie achter op mijn blog posts. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We hopen er met z'n allen iets moois van te maken!&lt;/p&gt;&lt;img src="http://community.dotned.nl/aggbug.aspx?PostID=994" width="1" height="1"&gt;</description></item></channel></rss>