Welcome to EMC Consulting Blogs Sign in | Join | Help

David Wynne's Blog

  • iPhone 4.0 Announced: Does Windows Phone 7 Lack Ambition?

    Earlier this week I summarised what I’d learnt about Windows Phone 7 (WP7) whilst at Mix 10.  I made the point that WP7 did not look like an iPhone killer primarily because they were following the iPhone playbook, just a few years behind.

    Well with the announcement of iPhone OS 4 yesterday that appears to have been confirmed sooner than I imagined.  Furthermore Apple look to be squarely focused on matching some of the features that made WP7 unique.  “Game Center… will bring features like a social gaming network, the ability to invite friends to games, leaderboards, achievements, and the opportunity for matchmaking."  Xbox Live anyone?  Now obviously the Xbox Live service has a major head start and cross platform goodness, but it doesn’t take away the fact that WP7 has lost one of it’s USPs.

    Apple also announced that Multitasking was finally coming with OS 4.0.  Given that Android already has this – WP7 is already looking like the ugly duckling on the multitasking front.  When it was confirmed at Mix that WP7 wouldn’t support multitasking, you could almost hear the collective rolling of eyes.

    What irks me is that Microsoft have the advantage of being late to the game – they can look at everything Apple and Android have done; what worked well and what didn’t and then focus on solving the stuff others did poorly.  Multitasking is was the top *** about the iPhone (almost to the point of tedium) so why didn’t Microsoft take a deep breath and say “right – let’s nail that”?

    I really hope Microsoft have an ace up their sleeve.  Frankly the impression I got from Mix was that they’ve got so much work left to do on what they’ve already announced, this seems unlikely.

    So where does this leave WP7?  What’s important now is that whatever they do end up releasing is solid; really solid.  WP7 is surely Microsoft’s first step in a longer journey.  If they manage to get “it’s a really good device, but not quite an iPhone” status – that would be a good result.  If they launch too early, with a poor set of features to-boot.  Well.  You only have to look at previous Windows Phone devices to see where that would leave them.

  • Windows Phone 7 [First Impressions]

    So the headline of Mix was Windows Phone 7, Microsoft’s rewrite of their previously broken mobile phone platform.  The headlines, as I'm sure everyone now knows (and some predicted) is that Silverlight and XNA take front and centre when it comes to authoring apps and games on Windows Phone 7.  This is awesome.  I am both a Silverlight and XNA developer already; now I'm also a WP7 developer.

    The device itself presented little surprises: GPS, Accelerometer, Rear Camera (some models might also have a front camera) and is primarily touch based (but some models with have a actual keyboard too).

    The phone should be released “in time for Holiday [Christmas] 2010” – reading between the lines that probably means sometime around October, so people have time to buy it for Christmas.

    The Good

    • Active Sync is now dead - thank god, what a terrible pain in the *** that's been over the years.  The desktop Zune software is now the companion software.
    • Wireless sync on connect of power.  If the phone’s charging and detects your home wireless network; it will attempt to sync over Wi-Fi with your computer.  Fantastic feature – still don’t understand why the iPhone doesn’t have this.
    • Microsoft “have committed” to pushing the Silverlight model to the Xbox Platform (although no actual 
      announcement on that front is being made).
    • All the UI goes through Direct 3D and thus the GPU

    The Bad

    • Terrible name, everyone was verbally tripping over it all week at Mix.  Hopefully that will change.
    • No Copy/Paste – this slipped out during one presentation, although they weren’t keen to talk elaborate on it much.
    • The phone will launch with a superset of Silverlight 3.  MS weren’t that keen to go into much detail here, other than to give the impression it’s a fork of SL3 optimised for the phone, with some SL4 features thrown in.  This is a shame as SL4 has some fundamentally improved stuff in it – such as a new XAML parser.  It’s also not generally a fantastic idea to start splintering frameworks.

    The Interesting

    • Apps can’t be run in the background (ala iPhone).  They’re paused when a user navigates away from them and maybe killed if memory needs reclaiming.
    • SQL Compact is on the phone but not exposed to Developers in this release.
    • Silverlight like Isolated Storage is the place to store stuff locally within your apps.  There’s no limit to how much space an app can use, so instead of IsolatedStorageFile.AvailableFreeSpace returning the space allocated to your app, it returns to total space left on the phone.  (This is the combination of the phone memory and SD Card – you can’t target the SD card specifically).
    • Apps can’t share/access Isolated Storage.
    • Standard controls, such as ListBox, get Pan/Flick support for free.
    • Both XNA and SL apps with have access to the Xbox Live Game Services.
    • The focus for this release (re: Xbox Live) is turn based games, rather than real-time multiplayer.
    • Both SL and XNA apps are deployed as XAP files.
    • The emulator has no support for testing Accelerometer, Vibration or GPS related functions.
    • The CTP does not include the Bing Maps control – but there will be one for launch.
    • The location API (GPS etc) is the same as that of Windows 7.

    The Hardware

    Microsoft are not taking the Apple route when it comes to the hardware, but rather sticking with their model of laying down the minimum specs and then allowing OEM partners to create devices that may meet or exceed that spec.  I'm undecided as to whether this leads to healthy competition resulting in better devices or inconsistency (eg. some devices will have a hardware keyboard/front facing camera, some will not.)  The track record of Windows Phone hardware is littered with terrible models, so there's a trend that needs bucking.  The hardware is going to be so fundamentally important to the success of WP7 that only time will tell as to whether this is a sensible approach.

    Is it an iPhone Killer?

    No.  Microsoft are essentially playing the iPhone playbook.  The device specs are comparable to the iPhone 3GS, they’re going to launch with no copy/paste, there’s a Market Place (read: “app store”), apps can’t run in the background etc etc.  So whilst this is progress – it’s not going to be an iPhone killer.  By the time WP7 launches the iPhone 4 will surely be hot on it’s heels and will surely introduce more sensors/hardware devices, leaving WP7 looking out-dated already.

    Microsoft either have a surprise up their sleeves that they haven’t announced yet, or are playing the long game as they did with the Xbox.  They realise they’re not going to trump the iPhone in a single move, but this lays the foundations for that move to happen in a few years time.

    In Conclusion

    I love the programming model – it’s so obvious and makes so much sense that it’s almost not exciting (but of course it is).  When Microsoft enable you to push Silverlight apps to the Xbox as well they really have a truly compelling range of platforms for Silverlight and XNA to run upon.

    The hardware is my main concern.  If they get that right, they’re in with a chance.  Get that wrong and they’re behind by a few years again.

    From what I saw of the phone at Mix (we weren’t allowed to touch it) – they have a lot of work left to do, and not a whole lot of time in which to do it.  I want it to be a success – so I’m hopeful.

  • WPF, Model-View-ViewModel (MVVM), MEF and other Acronyms

    IMG00041

    Stuart Harris and I have been working on a new WPF project of late, one aspect of which needed to support a plug-in type model so we decided to try out MEF (Managed Extensibility Framework) and were both pretty impressed – as Stu has been evangelising.  We were also keen to try and bring some of the MVVM goodness we’d been using on our last few Silverlight projects into the mix and thought we’d try and come up with a pattern of using MEF as the IoC container aspect in WPF.

    It’s still early days on the project so I’m sure we haven’t hit all the issues that may be inherent in our current implementation, but I thought I’d throw together a quick sample of the approach we’re taking right now.

    The Plan

    In Silverlight we’d been using Ninject as the IoC container and the basic execution flow goes something like this:

    • View (User Control XAML) – added to Page.xaml (the application Root Visual) and so instantiated by the application.
    • View’s Data Context set to a ViewModel via a specific property on the ServiceLocater class
    • ServiceLocater class setup as a Resource in App.xaml (so instantiated for us and available to everything)
    • ServiceLocater exposes a property per ViewModel, its get accessor makes a request to Ninject’s kernel for the ViewModel which then deals with instantiation and injection of that ViewModel and related dependencies.

    We wanted to have more or less the same execution, but with MEF pulling the strings.  We wanted to be able to set the DataContext of a View in its XAML so Resharper can resolve it and give you IntelliSense to the associated ViewModel in XAML which is really handy.  We were also quite keen to try and get rid of the ServiceLocater class if possible, which is basically continually growing boiler plate code.

    Introducing MEF

    MEF is all about composable parts, which come in two flavours; imports and exports.  An export is something you want to share and an import is the point at which you want to inject an export.  So in the MVVM pattern your ViewModel is an export which get’s imported into the View.  Any dependencies the ViewModel may have are also exports and imported, or injected, into the ViewModel.

    Like other IoC containers MEF needs to a way of knowing about what exports it has at its disposal and what imports require “composing” (or matching up to available exports).  In MEF this is the CompositionContainer which contains a Catalog of exports – this is the doorway to some of MEF’s cooler features (like monitoring directories for updated/new exports etc) but in our case we’re keeping it simple and will build the catalog using the executing assembly.  (i.e. MEF will examine the executing assembly for anything marked as an Export and add it to the catalog).

    MEF will take care of instantiating classes marked for Export for us and managing their dependencies and lifetime.  But it won’t magically do the same for classes that only has imports, such as our View.  So we need to not only instantiate the View ourselves but also tell MEF that it now exists and wants its imports satisfying (“composing”).

    Here’s the basic order of execution we want to achieve, we’ll step through each stage with code samples shortly.

    • Application Starts
    • Create the CompositionContainer with a catalog of exports based on the executing assembly
    • Main Window gets instantiated by App.xaml
    • Main Window instantiates the User Controls contained in it.
    • In the Constructor of each User Control, it adds itself to the Composition Container via the Compose method.
    • In doing so, its Imports are satisfied – if this includes Exports (such as a ViewModel) that have not yet been instantiated, they get instantiated by MEF and its imports satisfied and so on.

    Some Code

    I’ve refactored my previous feed reader example built using Silverlight and Ninject to WPF using MEF.  It essentially grabs the latest items from a Digg RSS feed and displays them in a list box.  Check out the previous post for more info.

    App Start
    First we create the CompositionContainer, adding a catalog of exports found in the executing assembly.  We’re also exposing the Composition Container as an internal static so views can add themselves later.

    public partial class App
    {
        private static CompositionContainer container;
    
        internal static CompositionContainer Container
        {
            get
            {
                return container;
            }
        }
    
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
    
            var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            container = new CompositionContainer(catalog);
        }
    }

    The View
    FeedReaderView.xaml is added to the MainWindow and so get’s instantiated for us.  In the code behind of the view we want to create a ViewModel property to which we will set the view’s DataContext.  To get the ViewModel to import into this property we need to ask the Composition Container to compose our view.  This is easily accomplished by hitting the static internal Container property we exposed from App.xaml.cs.  Since this is something every view is going to have to do in the same way, we created an extension method to keep the view’s code behind succinct.

    public static class UserControlExtensions
    {
        public static void RegisterWithContainer(this UserControl view)
        {
            try
            {
                var batch = new CompositionBatch();
                batch.AddPart(view);
                App.Container.Compose(batch);
            }
            catch (CompositionException compositionException)
            {
                MessageBox.Show(compositionException.ToString());
            }
        }
    }


    public partial class FeedReaderView
    {
        public FeedReaderView()
        {
            this.RegisterWithContainer();
            this.InitializeComponent();
        }
    
        [Import]
        public FeedReaderViewModel ViewModel
        {
            get;
            private set;
        }
    }

    Notice that the call to RegisterWithContainer (the extension method) takes place before InitializeComponent, it’s important the ViewModel property is assigned a value before you try and use it as the DataContext.  If it’s null when the DataContext is set – data binding kinda blows up.

    Finally we can now use our ViewModel as the DataContext – whilst you could set this in the code-behind, if you’re using Resharper then you definitely want to do this in the XAML.  Resharper will resolve the bindings and give you intellisense through to your ViewModel properties in the text editor, which is really rather funky.

    <UserControl x:Class="MVVMWithMEF.UI.Views.FeedReaderView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 x:Name="view"
                 DataContext="{Binding ElementName=view, Path=ViewModel}">
        ...
    </UserControl>

    The ViewModel
    The ViewModel side of things is very simple.  All we need to do is add an Export attribute to the class and in our case inject our feed service via some constructor injection:

    [Export]
    public class FeedReaderViewModel : BaseViewModel
    {
        [ImportingConstructor]
        public FeedReaderViewModel(IFeedService feedService)
        {
            ...
        }
    
        ...
    }

    Since we’re injecting (or importing) IFeedService this too needs to be marked up for export.  At this stage we’re going to export an RssFeedService implementation of IFeedService so to get our contracts to match we need to specify the export contract as conforming to the interface.

    [Export(typeof(IFeedService))]
    public class RssService : IFeedService
    {
        ...
    }

    And that’s all there is to it.  Download the code below, take a look, read Stu’s blog and tell us what you think.

  • Handy Code: ThrowIfNull Extension Method

    Checking whether an object is Null before using it and throwing a Null Reference Exception if it is indeed Null, is a pretty repetitive task.  Seeing code like this is not unusual:

    private readonly List<string> people;
    private readonly List<string> tasks;
    
    public Without(List<string> people, List<string> tasks)
    {
        // Null Checking
        if (people == null)
        {
            throw new NullReferenceException("people is Null");
        }
    
        if (tasks == null)
        {
            throw new NullReferenceException("tasks is Null");
        }
    
        // Field Initialisation
        this.people = people;
        this.tasks = tasks;
    
        // Actual code we care about here.
    }

    This kinda get’s my aesthetic coding back up, it’s repetitive, wordy and defocuses our code from the job of doing something useful.  Enter a generic extension method to take away the pain:

    public static T ThrowIfNull<T>(this T value, string variableName) where T : class
    {
        if (value == null)
        {
            throw new NullReferenceException(string.Format("Value is Null: {0}", variableName));
        }
    
        return value;
    }

    Now we can refactor our original code to the following:

    private List<string> people;
    private List<string> tasks;
    
    public With(List<string> people, List<string> tasks)
    {
        // Field Initialisation
        this.people = people.ThrowIfNull("people");
        this.tasks = tasks.ThrowIfNull("tasks");
    
        // Actual code we care about here.
    }

    What’s more, because our extension method ultimately returns the object upon which it’s being enacted, we can chain methods to make even more succinct code:

    private void AlternativeUse(List<string> places)
    {
        places.ThrowIfNull("places").Add("Home");
    }

    Happy coding.

  • Silverlight User Group – Link Dump

    Stuart Harris and myself presented at the 5th Silverlight UK User Group this evening and I thought I’d throw up a bunch of [hopefully] useful links on some of the stuff we covered.  For those of you who weren’t lucky enough to be in attendance we were talking about a PoC (Proof of Concept) we did with Microsoft for National Rail Enquires a few months ago at Microsoft UK’s MTC (Microsoft Technology Centre).  Stuart has blogged about it before – so head over to his blog for a more rounded err… roundup.

    Silverlight & Virtual Earth

    • Deep Earth (live demo)
      Virtual Earth and Silverlight funkiness – pretty much the bed rock of our implementation (we even get a link back on their CodePlex page!)
    • MIX 08 Session where Virtual Earth Silverlight SDK was announced
      There’s about 5 mins right at the end of this presentation that discusses the up coming official Silverlight Virtual Earth SDK.  Short demo, not many details – looks very close to Deep Earth in terms of functionality but a bit more polished.
    • VIEWS – Virtual Earth Wrapper for Silverlight 
      A Silverlight managed wrapper for the Virtual Earth Web Control.  I discovered this post-PoC, when doing some presentation research so can’t talk with much authority, but if you’re wanting to do Silverlight Virtual Earth stuff might be worth a look.
    • Quick Graph
      Graph data structures and algorithms in .Net which we used to model the Rail Network

    Train Related

    • NRE Web Services
      These public web services are a subset of the private services we used in our State Service.  Whilst you don’t get quite the depth of data we used, you can still get hold of a lot of real time arrivals/departures data - certainly enough for any number of train related mash-ups.
    • Rail Network – Route Plans
      Not very techy – but they were useful when we were doing this PoC, so if you start messing with the Web Services yourself you might also find them useful.
    • Phil’s Web Pages (search for CRS codes via Google)
      Again not very techy, but this website from a chap with too much time on his hands was really useful when working with the CRS (station) codes returned by the NRE Web Services.

     

    Thanks for all those who attended – hope you enjoyed it.

    If you’d like to come the next (as yet unscheduled) Silverlight UK User Group then get your name down.  Space is often quite limited and I know we were massively over subscribed this time round which is great!

  • Silverlight and the View-ViewModel Pattern

    ViewModelUI The last few WPF/Silverlight projects I’ve worked on we’ve been implementing using the View-ViewModel Pattern, which has worked really well for us – creating  testable code with a good separation of concerns.  I recently knocked up a very simple Silverlight solution to demonstrate the key aspects of the pattern to a colleague and it seemed to do a pretty good job of conveying the headlines and benefits pretty quickly so thought I’d chuck it up here as well, with a little walk through.

    The Application

    We’re going to build a simple application that will retrieve a feed (in this case Digg’s main RSS feed) and then display the items in a ListBox.  The only other functionality we’ll be offering is the ability to manually refresh the feed.  Our business rules state that whilst the feed is updating, the Refresh button must be disabled and the Status displayed.  That’s it - exciting huh?

    To make this app you will need:

    The View

    In the View-ViewModel Pattern, your XAML (in our case PageView.xaml) is the View.  This is bound to an associated ViewModel (in our case PageViewModel.cs).  Our aim is to make the View as dumb as possible (read: “ideally no code in PageView.xaml.cs”) and push all logic back to the ViewModel.  Whilst the View is aware of the the ViewModel (via binding), the ViewModel is not aware of the View.  This separation makes our ViewModel extremely testable and the View a largely Designer only realm.

    Let’s take a look at some code, then we’ll dissect it.  Below is the code for PageView.xaml, with the class diagram of PageViewModel along side:

    <UserControl x:Class="StandardViewModel.View.PageView"PageViewModelClass 
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:input="clr-namespace:StandardViewModel.SLExtensions.Input"
                 Width="400"
                 Height="300"
                 DataContext="{Binding Path=PageViewModel,
                                       Source={StaticResource ServiceLocator}}">
        <Grid x:Name="LayoutRoot"
              Background="White">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <ListBox ItemsSource="{Binding Path=Items}"
                     Grid.Row="0"
                     Margin="5,5,5,5" />
            <Grid Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="Status:"
                           Grid.Column="0"
                           Margin="3,3,3,3" />
                <TextBlock Text="{Binding Path=Status}"
                           Grid.Column="1"
                           Margin="3,3,3,3" />
                <Button Content="Refresh"
                        Grid.Column="2"
                        Margin="3,3,3,3"
                        IsEnabled="{Binding Path=IsRefreshEnabled}"
                        input:CommandService.Command="RefreshCommand" />
            </Grid>
        </Grid>
    </UserControl>

    Things to note:

    • Besides the standard call to InitializeComponent() – there is no code what so ever in PageView.xaml.cs
    • The DataContext for the whole UserControl is set to PageViewModel
      • Ultimately the instantiation of PageViewModel is handled for us by Ninject, which I’m not really aiming to cover in this post – download the source code if you want to see how that’s wired in, it’s fairly straightforward.
    • Everything is bound to properties in the ViewModel.
    • The ViewModel implements INotifyPropertyChanged.
    • In the ViewModel IsRefreshEnabled and Status both raise the PropertyChanged event (when their values are changed) and Items is of type ObservableCollection<string> (thus raising the CollectionChanged event when it’s contents are changed).
    • The Refresh button has an additional attached property, this is the Silverlight Extensions WPF-like Command implementation.
      • This will raise CanExecute and Executed events (ala WPF), that we can subscribe to and handle in the ViewModel.

    We’re pretty much done with PageView.xaml  and can now concentrate on building our ViewModel to behave correctly, safe in the knowledge data-binding will take care of updating our UI.  Since PageViewModel is just a POCO – we can approach this in a TDD manner should we wish, writing Unit Tests against it and then implementing the logic to satisfy the test.

    The Model

    Although in this example I’m processing an RSS Feed, I don’t want to tie the application to that format, so we’ll implement an IFeedService interface that exposes a GetFeed method and a GetFeedCompletedEvent (raised when the feed has been fetched and parsed).  The event returns GetFeedCompletedEventArgs, in which will be a List of FeedItem objects.  The actual logic for fetching and parsing an RSS feed will be in RssFeedService, which implements IFeedService.  Queue class diagram:

    IFeedService

    The ViewModel

    The only thing our ViewModel now needs to know about is IFeedService, which it will accept as a parameter in it’s constructor.  In our application Ninject will bind IFeedService to RssService (letting Ninject take care of instantiation and injection at runtime) and in our unit tests we can write a MockFeedService that implements IFeedService and then use that to instantiate an instance of PageViewModel against which to test.

    Our MockFeedService allows us to specify how many items it should generate via a constructor parameter, so we can test that the PageViewModel.Items collection ends up with the correct number of items.  Our Unit Test that checks the ViewModel is initialised correctly might look something like this:

    [TestMethod]
    [Description("Test that the model is correctly initialised at startup")]
    public void StartupTest()
    {
        // Generate 5 Items
        MockFeedService mockFeedService = new MockFeedService(5);
        PageViewModel pageViewModel = new PageViewModel(mockFeedService);
    
        Assert.AreEqual(Status.Ready, pageViewModel.Status);
        Assert.AreEqual(mockFeedService.FeedItems.Count, pageViewModel.Items.Count);
        Assert.IsTrue(pageViewModel.IsRefreshEnabled);
    }

    And the key bits of code from PageViewModel that make that test pass are below (download the source code for the whole thing):

    [Inject]
    public PageViewModel(IFeedService feedService)
    {
        this.feedService = feedService;
        this.Items = new ObservableCollection<string>();
    
        this.WireUpEvents();
        this.CallFeedService();
    }
    
    private void WireUpEvents()
    {
        this.feedService.GetFeedCompleted += this.FeedService_OnGetFeedCompleted;
    
        Commands.RefreshCommand.CanExecute += (sender, e) => e.CanExecute = this.IsRefreshEnabled;
        Commands.RefreshCommand.Executed += this.RefreshCommand_OnExecuted;
    }
    
    private void CallFeedService()
    {
        this.Status = Status.Updating;
        this.Items.Clear();
        this.feedService.GetFeed();
    }
    
    private void FeedService_OnGetFeedCompleted(GetFeedCompletedEventArgs args)
    {
        if (args.Result != null)
        {
            foreach (FeedItem feedItem in args.Result)
            {
                this.Items.Add(feedItem.Text);
            }
    
            this.Status = Status.Ready;
        }
    }

    The Source Code

    You can download the Source code below which contains all the core components and a number of Unit Tests to play with – set the StandardViewModel.Test project as the start-up project and hit F5 to run them.

  • Silverlight Treemap Algorithm

    TreemapNotebook I recently had a requirement to deal with displaying groups of dynamic data in Silverlight.  The data will come in a variable number of groups, with a variable number of items in each group.  In order to display all items correctly, groups that have more items in require more screen real estate than those with less items.  Whilst thinking through how I might spilt up the available screen space in that manner, it occurred to me that what I was essentially trying to create was a Treemap.  Generally speaking, a treemap is a type of graph - filling a given area with rectangles that vary in size to represent their relative value.

    Whilst doing some research into how treemaps are constructed I came across an old article on Code Project from 2004 where a chap had taken a somewhat obscure mathematical paper on a Squarified Treemap Algorithm from a Dutch University and created a C# implementation to run on Longhorn (this was 2004).  Now I’m sure Jonathan Hodgson (who wrote the Code Project article) won’t mind me saying his code was largely a prototype and logically not very close to the original algorithm.

    I decided to revert back to the original mathematical algorithm and try and come up with something that closely resembled it in C#.  Whilst the algorithm in the paper deals with calculating how many rectangles each row should contain and their size, it does not address plotting the results – so I also wanted to deal with this side of the puzzle (the call to LayoutRow).

    I was keen that the core algorithm be fairly independent of UI largely because I wasn’t going to use the output to actually draw a treemap (just designate areas of the screen in which to place other items) but also to make it portable to other platforms.  There’s nothing in the core algorithm I’ve written that couldn’t be ported to WPF or ASP.Net, or any other .Net environment very easily.  The output is a collection of Rect objects – which the consumer can use as they wish – be it to actually draw a Treemap or not.  The input is simply a list of values you want to plot and the dimensions of the area you want the Treemap to fill.

    I’m not going to step through all the gory details of the code (you can download the source below and do that yourself) – but after a fair bit of reading, thinking and a few pages of pseudo code I think I’ve come up with something pretty close to the original, or at least not bad for a first attempt.  (If you’re reading the source code along side the maths paper – I’ve renamed the function Worse to CalculateAspectRatio – otherwise the naming is pretty much the same).

    You can play with the result below and download the source code beneath that:

  • WPF/Silverlight Controls: Generic GetTemplateChild()

    If you’ve written a custom control in either WPF or Silverlight then you’re no doubt familiar with the OnApplyTemplate() method you override in order to initialise your child controls via the GetTemplateChild() method.  A typical (and in this case, fairly useless control) might look something like this:

    [TemplatePart(Name = "PART_ContentTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "PART_LabelTextBlock", Type = typeof(TextBlock))]
    public class MyControl : Control
    {
        private TextBox contentTextBox;
        private TextBlock labelTextBlock;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.contentTextBox = this.GetTemplateChild("PART_ContentTextBox") as TextBox;
            if (this.contentTextBox == null)
            {
                throw new Exception("Couldn't find PART_ContentTextBox");
            }
            this.labelTextBlock = this.GetTemplateChild("PART_LabelTextBlock") as TextBlock;
            if (this.labelTextBlock == null)
            {
                throw new Exception("Couldn't find PART_LabelTextBlock");
            }
            this.contentTextBox.Text = "Contents";
            this.labelTextBlock.Text = "Label";
        }
    }

    Now whilst there’s nothing wrong with that, there’s some code duplication going on and for each child control I need 5 lines of code.  This is gonna get kinda messy for anything more than a simple control.  The major cause of the code bloat is GetTemplateChild() which returns you a DependencyObject requiring the need to cast, which in turn requires null checking.  This code would look so much nicer if only GetTemplateChild() were a generic method… so let’s refactor our code so that it is.

    [TemplatePart(Name = "PART_ContentTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "PART_LabelTextBlock", Type = typeof(TextBlock))]
    public class MyControl : Control
    {
        private TextBox contentTextBox;
        private TextBlock labelTextBlock;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.contentTextBox = this.GetTemplateChild<TextBox>("PART_ContentTextBox");
            this.labelTextBlock = this.GetTemplateChild<TextBlock>("PART_LabelTextBlock");
            this.contentTextBox.Text = "Contents";
            this.labelTextBlock.Text = "Label";
        }
        private T GetTemplateChild<T>(string childName) where T : DependencyObject
        {
            T childControl = this.GetTemplateChild(childName) as T;
            if (childControl == null)
            {
                throw new Exception(string.Format("Couldn't find {0}", childName));
            }
            return childControl;
        }
    }

    Now that’s pretty sweet – our OnApplyTemplate() method is easier to read, more focused and requires less lines of code.  We’ve also centralised our error checking, removing the duplication.  Whilst this is cool, if we want to use this generic method in more than one control [without copying/pasting] it needs to live elsewhere.

    The major hurdle to overcome in this refactor is that GetTemplateChild() is a protected method defined in Control (i.e. only available to inheritors).  As such, an extension/static method isn’t going to give you access.  After a bit of a 3-way messenger convo with Rich and Matt there were 3 options on the table, none of which were without flaw: create a base class to contain our generic GetTemplateChild<T>() method, use reflection to cheat, or implement an interface on which we can implement an extension method.  All have problems – but I’ve chosen to go with the interface/extension method implementation, which looks a little something like this:

    internal interface IGetTemplateChild
    {
        DependencyObject GetTemplateChildHelper(string childName);
    }
    internal static class ExtensionMethods
    {
        internal static T GetTemplateChild<T>(this IGetTemplateChild control, string childName)
                where T : DependencyObject
        {
            T childControl = control.GetTemplateChildHelper(childName) as T;
            if (childControl == null)
            {
                throw new Exception(string.Format("Couldn't find {0}", childName));
            }
            return childControl;
        }
    }
    [TemplatePart(Name = "PART_ContentTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "PART_LabelTextBlock", Type = typeof(TextBlock))]
    public class MyControl : Control, IGetTemplateChild
    {
        private TextBox contentTextBox;
        private TextBlock labelTextBlock;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.contentTextBox = this.GetTemplateChild<TextBox>("PART_ContentTextBox");
            this.labelTextBlock = this.GetTemplateChild<TextBlock>("PART_LabelTextBlock");
            this.contentTextBox.Text = "Contents";
            this.labelTextBlock.Text = "Label";
        }
        public DependencyObject GetTemplateChildHelper(string childName)
        {
            return this.GetTemplateChild(childName);
        }
    }

    For me it feels the lightest, most extensible and least intrusive.  The obvious downside is that we’ve broken encapsulation by essentially exposing the protected GetTemplateChild() method.  That said, it’s still a fairly elegant implementation and as all the options have their dark side, I think I’ll sleep tonight.  I’d certainly be interested in any other viewpoints or ideas – is there a flawless 4th way?

  • Getting Started with the Silverlight Unit Test Framework RC0

    I’ve just started looking at how we can leverage Jeff Wilcox’s Silverlight Unit Testing Framework in the current Silverlight project I’m working on.  There are some pretty long (and good) posts on Jeff’s blog about the framework that contain all the information I’m about to tell you, but if you want to get going quickly with the latest version – here’s what you need to know.

    If this is your first look at the framework, then Jeff’s post from March is a really good introduction to the top level benefits offered.  That post was written for the SL Beta 2 release (which contains 3 binaries and VS templates).  The RC0 release only contains 2 binaries and some breaking changes – Jeff has detailed the changes, but the headlines you care about for getting started are as follows:

    • There are now only 2 assemblies (Microsoft.Silverlight.Testing & Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight).  This is all you need.
    • The Project/Item templates from the Beta 2 release, don't add that much value and are aligned with pre-RC0 changes, so are best avoided at this point in time.
    • In your test project’s App.xaml cs Application_Startup() you no longer need to pass CreateTestPage() a reference to the application.
      • Example: this.RootVisual = UnitTestSystem.CreateTestPage();
        [ Previously you would have called CreateTestPage(this) ]
    • UI Tests, should now inherit from PresentationTest (not SilverlightTest)
    • Within UI Tests, TestSurface has been renamed to TestPanel
    • If you're writing anything that you want to be able to test, it cannot be private.  In Silverlight, you cannot use reflection to access private types and members [details].  To overcome this, you need to make methods you want to test (such as event handlers) internal, and add an InternalsVisibleTo attribute to the AssemblyInfo.cs in your target project, to allow the test project access.
      • Example: [assembly: InternalsVisibleTo("MyApp.Test")]

    If this is your first look at the framework, then the “headlines” above may not appear to simplify much, but I promise they do.  If you’re still skeptical, here’s a 3 point plan:

    1. Read the post from March
    2. Download the RC0 release
    3. Where something from the post in March doesn’t make sense/fit with the code in front of you, refer to the list above.

    So far, in my limited explorations, the RC0 release works without complaint against Silverlight RTW.

Powered by Community Server (Personal Edition), by Telligent Systems