Charlie Robbins A collection of technical thoughts http://www.charlierobbins.com//rss.xml/ en-us 40 Increase the performance of large WPF applications across the board <div class="hentry" id="article-increase-the-performance-of-large-wpf-applications-across-the-board"> <div class="entry-content"> <p>I was just debugging a very long render delay in some WPF code and I came across <a href="http://www.wpftutorial.net/MergedDictionaryPerformance.html">this little tidbit.</a></p> <p>The quote of interest is: “Each time a control references a ResourceDictionary XAML creates a new instance of it. So if you have a custom control library with 30 controls in it and each control references a common dictionary you create 30 identical resource dictionaries!”</p> <p>Normally that isn’t a huge problem, but when you consider the way that I personally (and have suggested to others) that they organize their resources in Prism projects it gets to be a <strong>serious</strong> problem. For example, let’s say we have this project structure:</p> <pre> /MyProject.Resources /Resources -Buttons.xaml -DataGrid.xaml -Global.xaml -Brushes.xaml -WindowChrome.xaml -Icons.xaml /MyProject.Module1 /Resources -Module1Resources.xaml (References all Dictionaries in /MyProject.Resources/Resources/*) /Views -View1.xaml -View2.xaml /MyProject.Module2 /Resources -Module2Resources.xaml (References all Dictionaries in /MyProject.Resources/Resources/*) /Views -View1.xaml -View2.xaml /MyProject.Shell /Resources -ShellResources.xaml /Views -MainShell.xaml </pre> <p>If in your views you reference the module-level ResourceDictionary (which helps for maintainability and modularity) then every time you create an instance of View1.xaml for example, you would have to parse all the ResourceDictionaries in /MyProject.Resources/Resources/* every time. And if in View1.xaml you have a reference to say View2.xaml now you&#8217;re parsing it all twice every time! This isn’t really a memory concern but it is a huge performance concern. There can potentially be thousands of lines of XAML code to parse and the time really does add up as your views become nested and more complex</p> <p>I recently switched all of the MergedDictionary references:</p> <pre> <code class="xaml"> &lt;ResourceDictionary&gt; &lt;ResourceDictionary.MergedDictionaries&gt; &lt;ResourceDictionary Source=”/SomeDictionary.xaml” /&gt; &lt;/ResourceDictionary.MergedDictionaries&gt; &lt;/ResourceDictionary&gt; </code> </pre> <p>To use the attached SharedResourceDictionary which shadows the Source property and keeps a global cache of all ResourceDictionaries parsed:</p> <pre> <code class="xaml"> &lt;ResourceDictionary&gt; &lt;ResourceDictionary.MergedDictionaries&gt; &lt;SharedResourceDictionary Source=”/SomeDictionary.xaml” /&gt; &lt;/ResourceDictionary.MergedDictionaries&gt; &lt;/ResourceDictionary&gt; </code> </pre> <p>And I saw a performance increase of almost two orders of magnitude: <strong>From almost 6000ms to 200ms.</strong> As always, this code is available on <a href="http://github.com/indexzero/wpf-samples">GitHub.</a></p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Tue, 11 May 2010 04:22:00 GMT http://www.charlierobbins.com//articles/2010/05/11/increase-the-performance-of-large-wpf-applications-across-the-board/ http://www.charlierobbins.com//articles/2010/05/11/increase-the-performance-of-large-wpf-applications-across-the-board/ MIX10 Keynote Redux : Windows Phone, and Silverlight 4 <div class="hentry" id="article-mix10-keynote-redux-windows-phone-and-silverlight-4"> <div class="entry-content"> <p>Although the software announcements made today were somewhat disappointing (no releases, just more betas, CTPs, and RCs) the cross-platform functionality offered by XNA 4.0, Silverlight 4.0, Visual Studio 2010, and Windows Phone 7 were compelling. A number of partners gave demos today that showcased some of the really interesting new features of Blend 4 Beta <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6f014e07-0053-4aca-84a7-cd82f9aa989f&amp;displaylang=en">[download here]</a> that I will be discussing more later tonight:</p> <ul> <li>eBay demos Desktop Simple Lister (with help from Cynergy)</li> <li>Netflix demos Smooth Streaming on WP7</li> <li>Foursquare demos location aware services WP7</li> <li>Other great demos: Seesmic, Major League Soccer, and Shazaam</li> </ul> <p>Another big announcement was that they&#8217;ve <em>open sourced the Silverlight media framework</em>, that was used to deliver the smooth-streaming HD experience for the 2010 Vancouver Olympic games. The code is available at http://smf.codeplex.com</p> <p>The focus was very strong on targeting multiple platforms that support Silverlight or XNA with <em>a single code-base</em>. This ubiquity of development has always been a major goal for Microsoft and so-far the case they&#8217;ve made is very compelling. I can&#8217;t wait to dig into the nuts and bolts of it and post more developer and designer focused analysis. </p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Mon, 15 Mar 2010 18:19:00 GMT http://www.charlierobbins.com//articles/2010/03/15/mix10-keynote-redux-windows-phone-and-silverlight-4/ http://www.charlierobbins.com//articles/2010/03/15/mix10-keynote-redux-windows-phone-and-silverlight-4/ MIX10 debuts 4s, 7s, and 10s <div class="hentry" id="article-mix10-debuts-4s-7s-and-10s"> <div class="entry-content"> <p>Microsoft made a flurry of announcements this morning via press release (link to come). As I watch Sterling Quinn, the 16-year-old Yo-Yo champ (20 minutes is too long for a warm-up FYI) I&#8217;ve read that Microsoft has:</p> <h4>&#8220;Announced the availability of comprehensive tools&#8221;</h4> <ul> <li>Visual Studio 2010 Express for Windows Phone</li> <li>Windows Phone 7 add-in to use with Visual Studio 2010 RC</li> <li>XNA Game Studio 4.0</li> <li>Windows Phone 7 Series Emulator for application testing</li> <li>Expression Blend for Windows Phone CTP</li> </ul> <h4>&#8220;Available for download today&#8221;:</h4> <ul> <li>Silverlight 4 RC</li> <li>Expression Blend 4 Beta &#8211; &#8220;New features such as Path Layout enable developers and designers to build and animate innovative user interface design via a groundbreaking visual layout mechanism, without the need to write code.&#8221; </li> </ul> <h4>&#8220;Several leading companies will be creating exciting applications and games for Windows Phone 7 Series.&#8221;</h4> <h4>&#8220;Silverlight adoption has continued at a rapid pace with installations approaching 60 percent of all Internet devices worldwide &#8211; an increase of nearly 15 percentage points in just four months.&#8221;</h4> <p><br/> More to come. Stay tuned in here or follow me on Twitter <a href="http://twitter.com/indexzero">@indexzero</a>.</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Mon, 15 Mar 2010 15:27:00 GMT http://www.charlierobbins.com//articles/2010/03/15/mix10-debuts-4s-7s-and-10s/ http://www.charlierobbins.com//articles/2010/03/15/mix10-debuts-4s-7s-and-10s/ Packed and ready for #MIX10 <div class="hentry" id="article-packed-and-ready-for-mix10"> <div class="entry-content"> <p><a href="http://live.visitmix.com">MIX10</a> gets started this Sunday. Looking forward to seeing what Microsoft et al. have up their sleeves for <a href="http://www.windowsphone7series.com/">Windows Phone</a>, Silverlight 4 and WPF 4. There also seems to be a stronger focus on web standards and Javascript this year:</p> <ul> <li><a href="http://live.visitmix.com/MIX10/Sessions/WKSP01">HTML5 Now: The Future of Web Markup Today (Part 1 of 2)</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/WKSP08">HTML5 Now: The Future of Web Markup Today (Part 2 of 2)</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX20">Building Great Standards-Based Websites for the Big Wide World with Microsoft ASP.NET 4</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX30">SVG: The Past, Present and Future of Vector Graphics for the Web</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX36">How jQuery Makes Hard Things Simple</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX22">Six Things Every jQuery Developer Muse Know</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/FTL01">Reactive Extensions for Javascript</a></li> </ul> <p>Here&#8217;s a list of some of the talks that I&#8217;m planning on attending:</p> <ul> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX54">An Enterprise Perspective on Silverlight 4</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/DS12">Total Experience: A Design Methodology for Agencies</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/CL52">Microsoft Silverlight Optimization and Extensibility with MEF</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX18">Developing Natural User Interfaces with Microsoft Silverlight and WPF 4 Touch</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX25">Design the Ordinary, Like the Fixie</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX12">Creating Effective Info Viz in Microsoft Silverlight</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/DS06">Touch in Public: Multi-touch Interaction Design for Kiosks and Architectural Experiences</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/DS05">Total Experience Design</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX02">The Mono Project</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/DS07">The Art, Technology and Science of Reading</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/DS08">Creating Great Experiences through Collaboration</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/WKSP07">Media Processing Workflow</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX21">Syncing Audio, Video and Animations in Microsoft Silverlight Applications</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/CL25">Microsoft Silverlight &#8220;Media&#8221; : Moving at 60fps</a></li> <li><a href="http://live.visitmix.com/MIX10/Sessions/EX33">Smooth Streaming Live in HD: 2010 Olympic Winter Games</a></li> </ul> <p>You can read more about my adventures on the floor at MIX10 by following me on Twitter, @indexzero, or checking back here periodically. Hope to see some of you there!</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Fri, 12 Mar 2010 21:10:00 GMT http://www.charlierobbins.com//articles/2010/03/12/packed-and-ready-for-mix10/ http://www.charlierobbins.com//articles/2010/03/12/packed-and-ready-for-mix10/ XamQuery: Reconciling the "theory" and "reality" of WPF vs. Silverlight <div class="hentry" id="article-xamquery-reconciling-the-theory-and-reality-of-wpf-vs-silverlight"> <div class="entry-content"> <p><b><em>Disclaimer: This technology does not actually exist yet, I am looking for feedback about this idea and anyone interested in working on it.</em></b></p> <p>I’m sure a lot of you have seen this image. It highlights some of the pain of working with Silverlight coming from a WPF background. </p> <p><img src="/assets/25/image.axd.png" height="450px" style="margin-left:150px" alt='silverlight-wpf-subset' /></p> <p>It occurred to me over the weekend that this is really a statement about <b><em>the consistency of the implementation of XAML DOM APIs.</em></b> With that in mind the next logical conclusion was that there is a very important parallel in the Javascript world, i.e. <b><em>the consistency of the implementation of the Javascript and HTML DOM APIs.</em></b> Thankfully since about 2005, much of this pain has been encapsulated into <a href="http://jquery.org">jQuery.</a></p> <p>So what about XAML? What can we do about it? This is where <b>XamQuery</b> would come in. Here’s a highlight of the core features I see and where I have needed them:</p> <ul> <li><p>A XAML DOM selector engine similar to Sizzle. Given that XAML doesn’t have complex selector syntax like CSS this would essentially be a highly optimized tree walker for the VisualTree that would wrap the disjoint APIs in WPF / Silverlight for getting visual parents and children.</p></li> <li><p>A set of fluent APIs for creating XAML DOM objects (Panels, Controls, etc) that would wrap some annoying inconsistencies when travelling between Silverlight and WPF as well as making it easier to do things in code that are <b>painfully verbose in pure XAML</b> (I think states of the VSM is a great example of this).</p></li> <li><p>A simple plug-in system for System.Interactivity Attached Behaviors to attach into. This would mirror the jQuery plugin system where each selector statement actually returns the jQuery object which you can then call plugins on.</p></li> </ul> <p>Feel free to contact me directly about this idea. I&#8217;m looking to get some like minded developers together to work on this. I think that this could be the thing that takes WPF and Silverlight development to the next level. </p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Mon, 22 Feb 2010 16:07:00 GMT http://www.charlierobbins.com//articles/2010/02/22/xamquery-reconciling-the-theory-and-reality-of-wpf-vs-silverlight/ http://www.charlierobbins.com//articles/2010/02/22/xamquery-reconciling-the-theory-and-reality-of-wpf-vs-silverlight/ Parsing JSON into dynamic objects using MGrammar and C# 4.0 <div class="hentry" id="article-parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0"> <div class="entry-content"> <p>I gave a talk last week at the <a href="http://njmsdev.org">New Jersey .NET User Meetup Group</a> on designing textual DSLs using MGrammar. You can download the slides here: <a href="/assets/19/Writing_Textual_DSLs.pptx">Textual DSLs with MGrammar</a>. The code portion of the project was focused around developing a JSON parser into dynamic objects in C# 4.0. JSON has become an increasingly popular data format over the last several years for it&#8217;s flexibility and simplicity. The entire JSON specification can be summarized in just five words: objects, arrays, values, numbers, and strings. Each of these diagrams has a clear representation in MGrammar shown below:</p> <h2>Objects</h2> <p><img src="/assets/20/object.gif" alt='json-object' /></p> <pre> <code> syntax Object = ObjectStart first:KeyValuePair rest:ObjectPart* ObjectEnd => Object { Pairs { first, valuesof(rest) } }; syntax ObjectPart = Comma pair:KeyValuePair => pair; syntax KeyValuePair = key:String Colin value:Value => Pair { Key { key }, Value { value } }; </code> </pre> <h2>Arrays</h2> <p><img src="/assets/21/array.gif" alt='json-array' /></p> <pre> <code> syntax Array = ArrayStart first:Value rest:ArrayPart* ArrayEnd => Array [ first, valuesof(rest) ]; syntax ArrayPart = Comma value:Value => value; </code> </pre> <h2>Values</h2> <p><img src="/assets/24/value.gif" alt='json-value' /></p> <pre> <code> syntax Value = string:String => string | number:Number => Number { number } | object:Object => object | array:Array => array | primitive:Primitive => Primitive { primitive }; </code> </pre> <h2>Numbers</h2> <p><img src="/assets/22/number.gif" alt='json-number' /></p> <pre> <code> token Number = Minus? Digit+ ('.' Digit+)? Exponent?; token Exponent = ("e" | "E") Sign? Digit+; token Digit = "0" .. "9"; token Sign = Plus | Minus; token Minus = "-"; token Plus = "+"; </code> </pre> <h2>Strings</h2> <p><img src="/assets/23/string.gif" alt='json-string' /></p> <pre> <code> syntax String = '"' text:(text:StringText | empty) '"' => String { valuesof(text) } ; token StringText = !('\u0022')+; </code> </pre> <h2>Inside the Parser</h2> <p>Much of the actual parsing is done using simple LINQ expressions. First through, you have to install Visual Studio 2010 and the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=29E4EAD0-FD81-42BA-862B-F3589378466A&amp;displaylang=en">SQL Modeling November 2009 CTP (formerly &#8220;Oslo&#8221;)</a> and created a new &#8220;Oslo Library.&#8221; This is important because it sets up all the M and MGrammar dependencies for you. </p> <p>After you&#8217;ve created your Oslo Library, you must add your *.mg file and set the build action to &#8220;MCompile.&#8221; This will use the <a href="http://msdn.microsoft.com/en-us/library/dd129517%28VS.85%29.aspx">M tools</a> to compile the *.mg file into a *.mx image. After that&#8217;s completed we can create our parser at runtime:</p> <pre> <code class="csharp"> MImage grammar = new MImage(@"jsonm.mx"); grammarParser = grammar.ParserFactories["jsonm.jsonm"].Create(); grammarParser.GraphBuilder = new NodeGraphBuilder(); </code> </pre> <p>Now that we have our parser we can use that to parse the raw text into MGraph:</p> <pre> <code> var inputText = new StringTextStream(sourceText); var errorReporter = new ParserErrorReporter(); Node rootNode = (Node)grammarParser.Parse(inputText, errorReporter); JsonmObject obj = ParseObject(rootNode); return obj; </code> </pre> <p>The rest of the process uses a series of LINQ expressions using some extension methods (included with the project). Here&#8217;s an example of how objects are parsed:</p> <p>private static JsonmObject ParseObject(Node objectNode) { JsonmObject jsonmObject = new JsonmObject();</p> <pre><code>List&lt;Tuple&lt;string, object&gt;&gt; keyValuePairs = objectNode .Edges.FindNodeWithBrand("Pairs") .Edges.FindNodesWithBrand("Pair") .Select(node =&gt; ParseKeyValuePair(node)) .ToList(); foreach (Tuple&lt;string, object&gt; pair in keyValuePairs) { jsonmObject.TrySetMember( new DynamicDictionaryMemberBinder(pair.Item1, false), pair.Item2); } return jsonmObject; </code></pre> } </code> </pre> <p>You can see in the above example that in addition to parsing the MGraph, it sets members on our <a href="http://blog.lab49.com/archives/3893">dynamic dictionary</a>. This is how we can parse some sample JSON like this:</p> <pre> <code> { "Object" : { "String" : "StringValue", "Number" : -1.4e1, "null" : null, "true" : true, "false" : false }, "Array" : [ "StringValue", 42, false, true, null ], "String" : "StringValue", "Empty" : "", "Number" : -1.4e1, "null" : null, "true" : true, "false" : false } </code> </pre> <p>Into a dynamic object using our parser like so:</p> <pre> <code> dynamic result = JsonmParser.Parse(new Uri(Environment.CurrentDirectory + @"\sample.json")); Console.Out.WriteLine(result.Object,String); // ==> "StringValue" </code> </pre> <p>As always this code is on <a href="http://github.com/indexzero/jsonm">GitHub</a>. I look forward to see more parsers in MGrammar in the future, send any MGrammar hacks my way in email or comments!</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Thu, 11 Feb 2010 20:11:00 GMT http://www.charlierobbins.com//articles/2010/02/11/parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0/ http://www.charlierobbins.com//articles/2010/02/11/parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0/ Capturing Raw Images from the Microsoft Surface <div class="hentry" id="article-capturing-raw-images-from-the-microsoft-surface"> <div class="entry-content"> <h2>Surface Multi-touch</h2> <p>As I mentioned in <a href="http://www.charlierobbins.com/articles/2009/12/25/adding-contactmultitap-to-the-microsoft-surface/">a previous post</a> the Microsoft Surface implements multi-touch using infrared computer vision as opposed to a capacitive approach. This is interesting for a couple of reasons. First it allows the Surface to recognize a <strong>very</strong> large number of touches. Second, it allows ambitious developers to tap directly into this infrared image data to perform more complex operations (like shape recognition). Getting at this information however is not entirely straight forward though. To simply things I created an attached behavior.</p> <h2>Attached Behaviors</h2> <p>Attached behaviors are something that I&#8217;ve <a href="http://www.charlierobbins.com/articles/2009/12/25/adding-contactmultitap-to-the-microsoft-surface/">blogged about</a> <a href="http://www.charlierobbins.com/articles/2009/07/13/robust-reusable-drag-drop-behavior-in-silverlight-3/">before.</a> They are a very convenient way to add user interface behavior to controls without having to implement a proper subclass. This behavior also implements a custom <a href="http://www.charlierobbins.com/articles/2009/07/13/robust-reusable-drag-drop-behavior-in-silverlight-3/">attached event</a>, which allows you to easily handle and process images captured from the Surface.</p> <h2>Using the Behavior</h2> <p>Using the behavior is simple; you just have to include the library in your solution, add the xmlns and set a couple of <a href="http://msdn.microsoft.com/en-us/library/ms749011.aspx">attached properties</a> and an event handler:</p> <pre> <code class="xaml"> &lt;s:SurfaceWindow behaviors:SurfaceWindowRawImageCapture.IsEnabled="True" behaviors:SurfaceWindowRawImageCapture.RawImageCaptured="YourEventHandler"&gt; (...) &lt;/s:SurfaceWindow&gt; </code> </pre> <h2>Optional Parameters</h2> <p>This behavior is designed to be flexible. There are several parameters that allow you to take advantage of this flexibility.</p> <p><strong>UseExplicitCapture=(true | false)</strong></p> <p>Setting this property to true will disable the attached event from being raised. It is false by default. Use it if you want to capture images programmatically which is explained below.</p> <p><strong>SaveTo=&#8221;C:\path\to\captured\images</strong></p> <p>Often it may be necessary to save the images that you capture to a specific location. If you set this property all images captured by the behavior will be saved to the specified directory.</p> <h2>Capturing Images Programmatically</h2> <p>The one drawback to the way that the Surface SDK allows developers to capture raw images is that the ContactDown event must be handled on the instance of the SurfaceWindow itself. What that means is that your attached event handler has to also be on the SurfaceWindow itself. The solution to this limitation is to call the behavior programmatically from your own code:</p> <pre> <code class="csharp"> SurfaceWindowRawImageCapture.CaptureRawImageAsync( Application.Current.MainWindow as SurfaceWindow, new Rect(100, 100, 100, 100), result => { // Code to execute when the result has been captured }); </code> </pre> <p>The Rect that is passed to the method defines an area to crop the entire Surface image. This is useful if you are only interested in a small sub-area of the total Surface. The callback that is passed to the method will be executed after the image has been captured. </p> <p>Let me know if you run into any issues with the behavior by emailing me: charlie [you know] robbins [obviously] gmail [you know] com. As always, all of this code is available under the MIT license on <a href="http://github.com/indexzero/bruce-wayne">GitHub</a>.</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Fri, 22 Jan 2010 05:25:00 GMT http://www.charlierobbins.com//articles/2010/01/22/capturing-raw-images-from-the-microsoft-surface/ http://www.charlierobbins.com//articles/2010/01/22/capturing-raw-images-from-the-microsoft-surface/