Compiled Experience Windows Platform Development http://compiledexperience.com en Thu, 24 Jul 2014 01:32:35 +0000 Thu, 24 Jul 2014 01:32:35 +0000 App state and Caliburn.Micro <p>As well as posting here a lot of things relating to Caliburn.Micro will be on the new official website. The first is the start of a <a href="http://caliburnmicro.com/announcements/application-state-part-1/">discussion of application state</a>.</p> Wed, 23 Jul 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/caliburn-state-1 http://compiledexperience.com/blog/posts/caliburn-state-1 nigel.sampson@compiledexperience.com (Nigel Sampson) Brand new website <p>Some of you may have noticed but I&#39;ve rebuilt the website / blog. Previously it was sitting as a custom Asp.Net MVC app running on <a href="http://azure.microsoft.com/en-us/">Azure websites</a> using SQL Azure as a back end.</p> <p>In an effort to try new things this new website is using <a href="http://jekyllrb.com/">Jekyll</a> and <a href="https://pages.github.com/">GitHub pages</a>. While setting up the new website was a piece of cake most of the work went into preserving as many existing uri&#39;s as possible.</p> <p>If I have missed any I&#39;d love to hear about them.</p> Mon, 14 Jul 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/new-website http://compiledexperience.com/blog/posts/new-website nigel.sampson@compiledexperience.com (Nigel Sampson) Building a colour palette for your app <p>When creating your app on both the phone and tablet almost all <a href="http://msdn.microsoft.com/library/windows/apps/dn439319.aspx">guidelines</a> will tell you create a consistent colour palette. There&#39;s a lot of tools out there to help you design your palette, <a href="https://kuler.adobe.com/">Kuler</a> from Adobe is a good example. But what&#39;s the best way to use our palette in your app?</p> <p>There&#39;s a couple of goals here, the first is we only want to have to define our colours once for the entire app. This way if we need to tweak them or do a wholesale replacement we&#39;re not spending hours hunting for every instance of that colour.</p> <p>The second is to provide an easy way to override existing theme resources.</p> <p>What I tend to do is create a separate resource dictionary for the palette, this is because it&#39;s usually imported into other dictionaries and I want to keep the repetition low. The other resource dictionary I&#39;ll create at this point is a theme overrides one, this contains all the redefinition of the built in resources using the new palette of colours.</p> <p>In our palette dictionary we&#39;ll want to define the colours and brushes separately, this is because despite most of the time we&#39;ll be using the brush there will be times the colour is required. Naturally the brush definition refers to the colour so we&#39;re sticking with our goals. Typically a colour / brush definition will look like:</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;Color x:Key=&quot;MajorAccentColor&quot;&gt;#FF2980B9&lt;/Color&gt; &lt;SolidColorBrush x:Key=&quot;MajorAccentBrush&quot; Color=&quot;{StaticResource MajorAccentColor}&quot;/&gt; </code></pre></div> <p>Sometimes your designs may make use of the same colour but with different alpha (or opacity) values. For me if this brush is going to be used through the app I&#39;ll define it within the palette like so:</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;Color x:Key=&quot;MinorAccentColor&quot;&gt;#FF80B929&lt;/Color&gt; &lt;SolidColorBrush x:Key=&quot;MinorAccentBrush&quot; Color=&quot;{StaticResource MinorAccentColor}&quot;/&gt; &lt;SolidColorBrush x:Key=&quot;MinorAccentOverlayBrush&quot; Color=&quot;{StaticResource MinorAccentColor}&quot; Opacity=&quot;0.5&quot;/&gt; </code></pre></div> <p>However if it&#39;s a one off I&#39;ll probably define the brush as inline XAML referring back to our colour resource.</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;controls:Sidebar x:Name=&quot;Sidebar&quot; IsExpandedChanged=&quot;OnIsExpandedChanged&quot;&gt; &lt;controls:Sidebar.Background&gt; &lt;SolidColorBrush Color=&quot;{StaticResource SidebarBackgroundColor}&quot; Opacity=&quot;0.5&quot;/&gt; &lt;/controls:Sidebar.Background&gt; </code></pre></div> <p>I try to name the colour / brush pairs in generic names more along the lines of their usage than what they look like colour wise. This is because they&#39;ll often be tweaked and it can look rather silly to have a resource named &quot;RedColour&quot; that&#39;s actually blue.</p> <p>Now our palette is defined let&#39;s make use of it, the first thing I go through and do is redefine quite a few of the out of the box theme resources to make the controls more in line with the rest of my app. It&#39;s these little bits that really polish an app, I die a little on the inside when I see the default purple in combo boxes and progress rings. I swear Microsoft chose that colour so people would be forced to deal with it but a lot don&#39;t.</p> <p>In my theme overrides resource dictionary I import the palette and start to define styles for the controls in terms of colours from the palette. We don&#39;t need to redefine every single resource, typically only the ones that add the accent colour. For instance with the ComboBox control the overrides are:</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;ResourceDictionary.MergedDictionaries&gt; &lt;ResourceDictionary Source=&quot;/Resources/Palette.xaml&quot;/&gt; &lt;/ResourceDictionary.MergedDictionaries&gt; </code></pre></div><div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;SolidColorBrush x:Key=&quot;ComboBoxItemSelectedBackgroundThemeBrush&quot; Color=&quot;{StaticResource MinorAccentColor}&quot; /&gt; &lt;SolidColorBrush x:Key=&quot;ComboBoxItemSelectedPointerOverBackgroundThemeBrush&quot; Color=&quot;{StaticResource LightMinorAccentColor}&quot; /&gt; &lt;SolidColorBrush x:Key=&quot;ComboBoxSelectedBackgroundThemeBrush&quot; Color=&quot;{StaticResource MinorAccentColor}&quot; /&gt; &lt;SolidColorBrush x:Key=&quot;ComboBoxSelectedPointerOverBackgroundThemeBrush&quot; Color=&quot;{StaticResource LightMinorAccentColor}&quot; /&gt; </code></pre></div> <p>That&#39;s pretty much it, a nice easy way to define your colour scheme realistically in any XAML app and reuse it well. </p> Thu, 10 Apr 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/colour-palette http://compiledexperience.com/blog/posts/colour-palette nigel.sampson@compiledexperience.com (Nigel Sampson) Caliburn.Micro and Universal Apps <p>There’s been a lot of announcements here at <a href="http://www.buildwindows.com/">Build</a> today, including the availability of the Windows Phone 8.1 SDK. This release brings a common Xaml UI framework between Windows Phone and Windows and some tooling support to enable you to easily share C# and Xaml between the two platforms called <a href="http://blogs.windows.com/windows/b/buildingapps/archive/2014/04/02/windows-store-universal-windows-app-opportunity.aspx">Universal Windows apps</a>.</p> <p>I’m also really pleased to say I’ve recently pushed the code to enable you to use <a href="https://github.com/BlueSpire/Caliburn.Micro">Caliburn.Micro</a> on the new frameworks. It’s available on <a href="https://github.com/BlueSpire/Caliburn.Micro">GitHub</a> and on <a href="http://www.nuget.org/packages/Caliburn.Micro/2.0.0-beta2">Nuget</a> under version 2.0.0-beta2, this version adds the new Windows Phone 8.1 platform to the Portable core assembly and appropriate Platform assembly.</p> <p>Because the new Windows Phone platform is closely aligned with the Windows platform you’ll notice that we build the app like it’s a Windows 8.1 app. For CM this means a few changes from Windows Phone 8, such as using CaliburnApplication rather than Bootstrapper, but for the most part most of the tutorials for using CM on Windows 8.1 will apply to Windows Phone 8.1. </p> <p>If you still want to build using the Windows Phone 8 Silverlight platform then WP8 version is still available from the same package and works just as it did before.</p> <p>To show off how powerful it is now the repository has a <a href="https://github.com/BlueSpire/Caliburn.Micro/tree/master/samples/CM.HelloUniversal">sample Universal app</a> where we share views and view models across both platforms, but still enable us to have custom views for shared view models. This coupled with Portable class libraries enables a variety of strategies to share code over many number of platforms. I’ll hopefully be covering a lot of these in the near future.</p> <p>As we get to grips with some of the stuff still to be announced over the coming days there should be more to add to this.</p> <p>On a related note I just want to thank <a href="http://www.markermetro.com">Marker Metro</a>, I wouldn’t have been able to get this release ready so quickly without their support.</p> Thu, 03 Apr 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/caliburn-micro-universal http://compiledexperience.com/blog/posts/caliburn-micro-universal nigel.sampson@compiledexperience.com (Nigel Sampson) DVLUP available in New Zealand <p>It&#39;s been a long time coming but I&#39;m really happy to say the Nokia developer reward program <a href="http://www.dvlup.com">DVLUP</a> is now available in New Zealand. We at <a href="http://www.markermetro.com">Marker Metro</a> have been working with Nokia to set up a launch here in Auckland. Come along to find out more about it and get a recap of the news and announcements from Build. <a href="www.dvlup.com/nigel.sampson/invite">RSVP here</a>.</p> <p>If you already want to sign up then use <a href="www.dvlup.com/nigel.sampson/invite">this link</a> and score me some bonus XP.</p> Tue, 01 Apr 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/dvlup-nz http://compiledexperience.com/blog/posts/dvlup-nz nigel.sampson@compiledexperience.com (Nigel Sampson) Using value converters by convention <p>The application of a convention in <a href="https://github.com/BlueSpire/Caliburn.Micro">Caliburn.Micro</a> is a bit of a pipeline with multiple steps, almost all of them we can modify, let&#39;s look at bringing value converters into the equation.</p> <p>Most of the time the default conventions tend to bring like-minded types together. That&#39;s natural in that conventions should be reasonably intuitive, like a string property on the view model being bound to the Text property of the TextBox.</p> <p>Sometimes these types don&#39;t always line up, which is where value converters typically come in. The most common of these being converting between boolean and visibility properties.</p> <p>Caliburn.Micro does a little bit of work here already, if a convention calls for properties of the two above types (boolean and visibility) then it automatically adds a BooleanToVisibilityConverter to the Binding.</p> <p>We can extend this through the modification of the <a href="https://github.com/BlueSpire/Caliburn.Micro/blob/master/src/Caliburn.Micro.Platform/ConventionManager.cs">ConventionManager.ApplyValueConverters</a> method, but why would we do this? In an app I&#39;m currently working on I want to use relative dates through the app, I&#39;m using a value converter that leverages the <a href="https://github.com/MehdiK/Humanizer">Humanizer</a> library (check it out if you haven&#39;t already) to do the conversion. This means everywhere I want to out put the date I need to dispense with the normal convention using x:Name and set up the binding with the value converter. A bit of a pain and there&#39;s always a chance I could miss one.</p> <p>What we need to do is modify Caliburn such that when it applies a convention between a DateTime (or DateTimeOffset) property and a TextBlock&#39;s Text when add the converter to the process.</p> <p>The code is pretty simple, the only weird part is taking a reference to the default implementation first so that we can keep the default behavior as well.</p> <div class="highlight"><pre><code class="csharp language-csharp" data-lang="csharp">var baseApplyValueConverter = ConventionManager.ApplyValueConverter; ConventionManager.ApplyValueConverter = (binding, bindableProperty, property) =&gt; { baseApplyValueConverter(binding, bindableProperty, property); if (bindableProperty == TextBlock.TextProperty &amp;&amp; typeof(DateTime).IsAssignableFrom(property.PropertyType)) binding.Converter = new RelativeDateTimeConverter(); if (bindableProperty == TextBlock.TextProperty &amp;&amp; typeof(DateTimeOffset).IsAssignableFrom(property.PropertyType)) binding.Converter = new RelativeDateTimeConverter(); }; </code></pre></div> <p>Now whenever a convention on a TextBlock is wired to a DateTime it will display a relative date time. We can remove all our bindings and converters from code and go back to simple x:Name conventions.</p> Thu, 27 Mar 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/value-converters-by-convention http://compiledexperience.com/blog/posts/value-converters-by-convention nigel.sampson@compiledexperience.com (Nigel Sampson) Some thoughts about custom Uri Protocols <p>I&#39;ve seen a lot of content around lately discussing the use of <a href="http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987(v=vs.105).aspx">custom uri protocols in your Windows Tablet and Phone apps</a>. They&#39;re a great way to have other apps launch your app in a deep link kind of way, however I don&#39;t think developers are really using them to their full potential.</p> <p><a href="http://blog.mrlacey.co.uk/2014/03/325-windows-phone-apps-you-can-launch.html">Matt Lacey</a> has a great post listing some of the 300 or so apps that implement custom uri protocols and their protocol name. Looking through the list a couple of things jump out at me.</p> <p>The first is that there&#39;s no documentation about the protocol itself, even with the protocol name from the list I have no real idea about how to use it. Some developers like <a href="http://lazywormapps.com/">Lazyworm Apps</a> have <a href="http://lazywormapps.com/metrotube-uri-schema.html">documented their metrotube protocol</a> but the amount that have are few and far between. There needs to be a central resource for this list including documentation.</p> <p>My second observation is that almost all the protocols are completely unique to that app, usually derived from the app name. This means that any other app is limited to launch that and only that app. The end user also doesn&#39;t have a choice of which app they want to use to handle that protocol.</p> <p>This problem is caused by a lack of global protocols besides the usual suspects of http, mailto etc. There are no established protocols for things like &quot;watch a youtube video&quot; leaving all the protocols as their own little islands.</p> <p>What I&#39;d love to see is the whole app protocol thing expanded so we can have a rich ecosystem of apps plugging into to fill different parts of a workflow, probably not going to happen but a guy can dream right?</p> Thu, 20 Mar 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/uri-protocols http://compiledexperience.com/blog/posts/uri-protocols nigel.sampson@compiledexperience.com (Nigel Sampson) Scaling with a PathIcon <p>The new <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.appbarbutton.aspx">AppBarButton</a> control in Windows 8.1 is incredibly useful, the ability to use symbols, gylphs, images or paths as an icon within the button makes it a lot easier to customise that in 8.0. There&#39;s just one slight problem. </p> <p><a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.pathicon.aspx">Path Icon</a> doesn&#39;t scale the Path geometry to fit within the button, it renders just as the Path geometry is specified which is kind of awkward. </p> <p>We could try and re-template PathIcon but that&#39;s probably overkill. The easiest thing to do is to rescale the Path, tools like <a href="http://www.inkscape.org/en/">Inkscape</a> would be one way to do it. Thankfully Christian Mosers has created a really simple tool to transform Path geometry down to the appropriate scale. It&#39;s called <a href="http://wpftutorial.net/GeometryTransformer.html">Geometry Transformer</a> and is available on his <a href="http://wpftutorial.net/GeometryTransformer.html">website</a>. </p> Thu, 13 Mar 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/scaling-pathicon http://compiledexperience.com/blog/posts/scaling-pathicon nigel.sampson@compiledexperience.com (Nigel Sampson) Custom Special Values in Caliburn.Micro <p><a href="https://github.com/BlueSpire/Caliburn.Micro">Caliburn.Micro</a> has features to allow you bind methods to actions with parameters. Check out the Action Parameters section of the <a href="https://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&amp;referringTitle=Documentation">documentation</a>. Part of this set of features includes &quot;special values&quot; such as $eventArgs or $dataContext, these allow an easy to access information contextual to the action. How can we use them?</p> <p>I use these special values in a number of different ways. When binding a list of values the item template may contain a button with the following:</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;Button Style=&quot;{StaticResource ContentButton}&quot; cm:Message.Attach=&quot;ViewSection($dataContext)&quot;&gt; </code></pre></div> <p>This action bubbles up to the root model passing the item in the list the button was pressed for.</p> <div class="highlight"><pre><code class="csharp language-csharp" data-lang="csharp">public void ViewSection(RepositorySection group) { } </code></pre></div> <p>Another is making use of the ItemClick functionality on GridView and ListView in Windows 8. This provides similar functionality without requiring buttons in your item templates. The difference is that clicked item is in the event args so I&#39;d use syntax something similar to:</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;ListView cm:Message.Attach=&quot;[Event ItemClick] = [SelectItem($eventArgs)]&quot; IsItemClickEnabled=&quot;True&quot;&gt; </code></pre></div><div class="highlight"><pre><code class="csharp language-csharp" data-lang="csharp">public void SelectItem(ItemClickEventArgs e) { } </code></pre></div> <p>Another example is around pinning tiles in Windows 8, for better user experience we want to pass an invocation point to SecondaryTile.RequestCreateAsync to ensure the popup is near the element that invoked it. You can get access to element using $source or the $executionContext.</p> <div class="highlight"><pre><code class="csharp language-csharp" data-lang="csharp">public async void ToggleTile(ActionExecutionContext context) { var transform = context.Source.TransformToVisual(null); var invocationPoint = transform.TransformPoint(new Point(0, 0)); ... } </code></pre></div> <p>While all these solutions solve the problem at hand they do make the code messier than I&#39;d ideally like. The ItemClick example forces you view model to depend on a xaml event args object with an internal constructor. While the invocation point sample forces the view model to start dealing with UI elements and their layout on the screen.</p> <p>So how do we solve these problems? We can actually create custom special values, this removes the weird dependencies on the view model and increases code reuse as the special values are only dealt with once. For the above examples we&#39;d have the following code in our bootstrapper (or application) depending platform.</p> <div class="highlight"><pre><code class="csharp language-csharp" data-lang="csharp">MessageBinder.SpecialValues.Add(&quot;$invocationpoint&quot;, c =&gt; c.Source.TransformToVisual(null).TransformPoint(new Point())); MessageBinder.SpecialValues.Add(&quot;$clickeditem&quot;, c =&gt; ((ItemClickEventArgs)c.EventArgs).ClickedItem); </code></pre></div> <p>Important points to note is that the key&#39;s must start with $ and be lowercase (they don&#39;t need to be in the xaml though). We can now change our xaml for our examples to the following.</p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;ListView cm:Message.Attach=&quot;[Event ItemClick] = [SelectIssue($clickedItem)]&quot; /&gt; </code></pre></div><div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;AppBarButton cm:Message.Attach=&quot;TogglePin($invocationPoint)&quot; /&gt; </code></pre></div> <p>There&#39;s a myriad of ways this trick could possibly be put to use. I&#39;m going back through old projects and looking where I&#39;m depending on special values and seeing if they can be simplified. </p> Sun, 02 Mar 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/special-values http://compiledexperience.com/blog/posts/special-values nigel.sampson@compiledexperience.com (Nigel Sampson) Views for types that aren't View Models <p>In most MVVM style frameworks we&#39;re used of seeing pairs of views and view models, RepositoryView and RepositoryViewModel for instance. We may sometimes have view models without views (such as GroupViewModel) but how do we deal with instances when we want views for types that aren&#39;t view models? </p> <p>I&#39;m currently redesigning and rebuilding bits of <a href="http://compiledexperience.com/windows-apps/hub-bug">Hub Bug</a> and making use of the <a href="http://octokit.github.io/">Octokit.NET</a> library from GitHub. This awesome nuget package provides 90% of what I&#39;d call my model. Often view models wrap these model types when bound to the view. Yet some of the smaller types such as <em>Label</em> and <em>User</em> may be bound directly to the view inside list boxes or form small parts of a large view. Creating view models just so Caliburn.Micro&#39;s <strong>ViewLocator</strong> can locate the correct view feels like a waste as the view models don&#39;t add any functionality and create unnecessary ceremony. </p> <p>By default Caliburn.Micro won&#39;t know what to do with these types, they don&#39;t end in &quot;ViewModel&quot; so it won&#39;t find any views. Even if it did it would try to locate them in the Octokit assembly which definitely isn&#39;t something we want. </p> <p>What we want to do is give the ViewLocator a hint that when it tries to locate views for certain types to look somewhere where it wouldn&#39;t normally look. In this case When it locates a view for <strong>Octokit.User</strong> I want to it to use <strong>HubBug.App.Views.Octokit.UserView</strong>. In application set up (either the Bootstrapper or the Application depending on platform) I have the following:</p> <div class="highlight"><pre><code class="csharp language-csharp" data-lang="csharp">ViewLocator.NameTransformer.AddRule( @&quot;^Octokit\.(\w*)&quot;, @&quot;HubBug.App.Views.Octokit.${1}View&quot;); </code></pre></div> <p>This uses lovely old regular expressions to transform the view model type to the view type, that&#39;s all it takes.</p> <p>What&#39;s very cool about this is that I now have a consistent way to display Users, whether I&#39;m binding to a ComboBox or it&#39;s part of a Grid. Caliburn makes sure I&#39;m using the correct view in every instance. </p> <p>For instance any where I want to display a user I can drop in the following xaml, tweak the binding appropriate to the view and I&#39;m done. </p> <div class="highlight"><pre><code class="xml language-xml" data-lang="xml">&lt;ContentControl micro:View.Model=&quot;{Binding Repository.Owner}&quot; FontSize=&quot;{StaticResource ControlContentThemeFontSize}&quot;/&gt; </code></pre></div> <p>ViewLocator has quite a few customisation options, take a look and see how you can streamline your app development.</p> Thu, 20 Feb 2014 00:00:00 +0000 http://compiledexperience.com/blog/posts/views-viewmodels http://compiledexperience.com/blog/posts/views-viewmodels nigel.sampson@compiledexperience.com (Nigel Sampson)