<?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 : Surface</title><link>http://community.dotned.nl/blogs/dennis_blog/archive/category/1020.aspx</link><description /><dc:language>nl-NL</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><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>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></channel></rss>