Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Friday, 5 July 2013

The Easy way to Record and Share Sermons - Introducing TruthVine Studio

One of my goals for TruthVine, my new sermon-sharing service, is to make recording and uploading sermons as easy as sending an email. All churches, great and small, should have the capability to share the Gospel online, not just those blessed enough to have an IT guru in the congregation.

To that end, I’m pleased to announce TruthVine Studio, free to all subscribers of the TruthVine service.

A screenshot of TruthVine Studio

Using this is simplicity itself:

  1. Press the big Record button when the preacher mounts the pulpit steps
  2. As he introduces his sermon, fill out the details in the relevant boxes
  3. Press the Stop button after the final “Amen”
  4. Hit Upload – and you’re done! The sermon will magically appear on your TruthVine powered website.

Should there be a period of paper shuffling before the preacher begins, you can easily trim the sermon before you upload it. Simply click and drag over the part of the recording you don’t want, then press the Trim (scissors) button.

Just think of the effort that saves you:

  • You don’t have to spend hours learning how to use complicated recording software.
  • You don’t have remember the sermon details to tag the files with later – type them straight into app.
  • You don’t have to spend ages waiting for your tool of choice to encode multiple versions of the file – TruthVine Studio exports a High Quality Mp4, a smaller Mp4 file, and an WMA file (for burning to CD) – and it takes advantage of your multi-core laptop to do all three at once.
  • You don’t have to go to a separate website, enter the sermon details all over again, then wait – again – whilst it uploads.

TruthVine Studio handles all of that in just a couple of clicks. We’ve been using TruthVine Studio at our church for the last couple of weeks at our church, and sermons have typically been on our church website within a minute of the service finishing.

If you fancy giving it a go, head over to the TruthVine site and sign up – it’s completely free during our preview period.

Shoutouts

I just wanted to say a few quick thank-yous to several folks for tools, resources and code that have been a huge help in building TruthVine Studio. In no particular order:

Tuesday, 14 August 2012

Data virtualization in Silverlight

When I first went freelance (15 months ago – how time has rocketed by!) I promised myself that, with the reigns of my schedule tightly held in my own fist, I would dedicate more time to blogging. Well! You can all see from my blog archives how that turned out. I have discovered that when you have clients willing to pay for as much time as you can give them, there’s a strange temptation to give them as much time as you’ve got!

However.

Just before I went on vacation last week, I found made the time to write a mini-blizzard of blog posts, though not for Functional Fun. Ayende, my client for the last few months, has published them on his company’s blog. In the first batch, I wrote about some exciting new features I’ve coded up for the user interface of RavenDb, Hibernating Rhino’s Document Database server.

But I think you’ll most enjoy a couple of posts I wrote about data virtualization in Silverlight. The problem is a common one. How do you display huge lists of data items in a client application without pulling data unnecessarily from the server? Often applications fall back on paging – show one page of data, and make the user click a Next button when they want to see more. But in terms of usability, this technique feels pretty neolithic. So I figured out a way of using ListBoxes and DataGrids without needing to load all the data up front, but with properly proportioned scrollbars, slurping data from the server just in time as the user scrolls.

Over on Hibernating Rhino’s blog you’ll find the two posts I wrote about this:

There’s also a bonus post on how I created a VirtualizingWrapPanel for Silverlight – built so that we could display data in a card view rather than a list view.

And best of all, I published a sample application on GitHub with all the code you need to use this technique in your own applications. For those WPF-aficionados amongst you, you should find that the code translates without much difficulty.

Monday, 12 March 2012

Fade-Trimming TextBlocks in Silverlight and WPF

Ayende just published a guest-post I wrote on his company blog:

Using ellipsis is so last year. When did you last see the cool HTML 5 kids writing … when they couldn’t fit all their text in a column? They’ve got this fancy new feature, powered by CSS3, where text that doesn’t quite fit simply fades out as it reaches the edge of the text block. Like this (with thanks to the QuickUI Catalog)

image

Subtle! It looks much prettier, and it means you can fit in an extra three characters of real text instead of the …s.

Silverlight’s future might be uncertain, but I want to show you that it isn’t ready to roll over and die just yet. We can have those fancy fade-trimming effects too!

As part of the work I’m doing on the UI for RavenFS, I implemented Fade-trimming to make our DataGrids look smarter, and I thought it would be nice to share. So I’ve packaged up all you need into an easy-to-use class called FadeTrimming.cs which works in Silverlight and WPF, and given you two demo projects to show you how to get started.

Read the whole article here

Saturday, 28 January 2012

Crunch, the RESTful Accountants (And Introducing the Crunch API Explorer)

One of the things that scared me a little when I thought about starting my own business was the thought of the bookkeeping. I know, I know – I have a Maths degree, so I ought to be able to cope with adding up a few numbers then working out the 20% I owe to the tax man. And the 20% I owe to the VAT lady. And how to take just the right amount of salary to avoid giving anything to the PAYE person. But my arithmetic has always been terrible, and the mathematicians who lectured me, strange to say, rarely used actual numbers. It was all xs and ys and βs and πs. So that didn’t help.

CrunchA big factor in persuading me to make the leap into running a company was finding an excellent online accounting service to handle all those troublesome numbers for me. Crunch are a smart bunch of accountants based down in Brighton who have teamed up with an equally smart bunch of developers to create bookkeeping software that is actually quite fun to use (I know – I couldn’t quite believe that when I read it on another freelancer’s blog, but it’s true!). You enter all the numbers in the website as you rake in the profits, or fork out to your suppliers, and at the end of the year, Crunch will put together your accounts and send them off to H.M.R.C. They’ll even submit your VAT returns for you. And handle your payroll, if you should happen to have any minions employees. All for £59.50 a month. It’s great. Sign up here and we’ll both get a £25 Amazon voucher!

And as if all that wasn’t awesome enough, earlier this month they launched an API. It its RESTful, speaking XML, with OAuth authentication. That’s right – a REST API from an accountancy company! I should caution that the first release is limited to dealing with expenses and suppliers, but the dev team plan to add areas according to the priorities indicated by us users.

The Crunch API Explorer

Well, you know me. I couldn’t leave a shiny new toy like that lying on the shelf. So I had a play, and knocked together something that I think you’ll like.

Allow me to introduce the Crunch API Explorer:

image

It’s a little tool to help you poke and prod the Crunch API. You enter a URL, set the appropriate Http Method, hit Go!, and it will show you the XML that Crunch returns.

You can download it here (it installs using ClickOnce, so it will auto-update when I add new features. If you don’t already have .Net 4.0 on your machine, you should be prompted to install it). To connect to Crunch using the Crunch API Explorer, you’ll need your own API key which you can get by contacting the nice folks at api-dev@crunch.co.uk. Then you can make REST calls to your hearts delight. All the documentation you need about the resource URLs and the structure of the XML for submitting updates can be found here on the Crunch website.

Here are a few of my favourite features:

  • XML Syntax colouring when you’re editing requests (this courtesy of AvalonEdit, the open source WPF text editor component that is part of SharpDevelop)
  • Makes you confirm any update/delete requests made to the live server (but not to the test server)
  • All the source is available on GitHub, so if ever you wanted an example of how to connect to an OAuth API with DotNetOAuth, well – now you have one (see CrunchFacade.cs). It’s all in C#, with some WPF, and of course a topping of MVVM.

There are a couple of things I wanted to add, but didn’t get time for – maybe next week:

  • Remembering frequently used resource URIs, and maybe saving template Xml request documents
  • Ability to choose a file and insert it into the XML request documents in Base64 format for the APIs that support file upload
  • Saving Base64 encoded data in the responses to files

Anything else?

I’d love to hear from anyone who finds this useful. Feature requests are welcome (pull requests even more so). And if you fancy forking this and adapting it to explore other APIs, be my guest.

Monday, 3 October 2011

Announcing the launch of Mixed In Key 5

I’m very pleased to announce that Mixed In Key LLC, one of my clients, have just launched the product I’ve been working on for the last eight months. Mixed In Key 5.0 is for DJs who put together their DJ sets using harmonic mixing, a technique for ensuring a musically pleasing transition from one track to the next by eliminating key clashes. Mixed In Key 5.0

How it works

The Camelot WheelMixed In Key supplies the key ingredient to successful harmonic mixing. It analyses every song in a DJ’s collection and determines which key it is written in (by key, I mean musical key, like C#, F#, A Minor, etc.). Every song is then added to a searchable database.

The other ingredient comes from music theory, and has been cleverly codified by Mark Davis into the Camelot Wheel. This shows the relationship between each key in a diagram arranged like a clock. To build a harmonic mix, a DJ finds the key of his first song on the wheel (so E Major is at the twelve o’clock position). For his next song he should pick one in a key which is an “hour” to the left or right, or stay at the same hour but switch between major or minor keys. Mixed In Key 5.0 includes a clickable Camelot Wheel to instantly search the database for songs in a particular key.

Under the bonnet

The User Interface is all built in WPF. As I hinted in an earlier blog post, I had a great time taking the designs beautifully drawn up for us in Photoshop by our designers and mapping them into XAML. Though I have to say, it is a painstaking process, poking all those pixels into precisely the prescribed positions – I guess it took something like 5 or 6 days to polish the 4 screens in the applications.

But more important than looking gorgeous, Mixed In Key 5.0 had to be fast and responsive (we started the project many months before Windows 8 was announced, otherwise that would have been “fast and fluid”). I have to thank the Task Parallel Library in .Net 4.0 for making this really easy to achieve (though not as easy as it will be in C# 5.0, when we get our hands on the await keyword).

At the heart of the application is song analysis, which is a process with several steps. First, we read the song data using some custom DirectShow filters (DirectShow is actually rather fun to use once you’ve got the hang of it). Then we send extracts of the data off to our analysis server in the cloud for processing. Finally we have to add it to the database. Each of the steps takes a while to complete, so are ideal candidates for Tasks.

.Net 4.5 has a rather nice Dataflow library that is ideal for setting up a pipeline of tasks that need to be processed asynchronously. But that’s not out yet, so I used some extensions that Stephen Toub wrote to the current TPL library for chaining Tasks together. Here’s what our analysis pipeline looks like:

AnalyzeSongAudio(progressReporter, file)
   .Then(audioAnalysis => file.AudioAnalysis = audioAnalysis)
   .Then(_ => ReadFileTags(file))
   .Then(tags => file.Tags = tags)
   .Then(() => SetItemStatus(file, QueuedFileStatus.DetectingKey))
   .Then(_ => DetectKey(file))
   .Then(result => file.SongAnalysisResult = result)
   .Then(_ => RewriteTags(file))
   .Then(result => AddSongToCollection(file))
   .Then(song => UpdateQueuedFileWithSong(file, song))
   .Then(() => SetItemStatus(file, QueuedFileStatus.UpdatingFile))
   .Then(() => UpdateFile(file))
   .Then(() => SetItemStatus(file, QueuedFileStatus.Completed))
.OnError(task => UpdateItemWithError(file, task.Exception.InnerException), Schedulers.UIThread)
.ContinueWith(t => DecrementQueuedFileCount(), TaskContinuationOptions.ExecuteSynchronously);

As an aside, do you know the best thing about using Tasks in your application? You get your free lunches back again! As PCs get more and more cores, your application will automatically scale to take advantage of them.

What a launch!

Yakov, the founder of Mixed In Key LLC, tells me that the launch has been very successful already.The Mixed In Key Twitter stream has been flooded with happy comments. Here are a few of my favourites:

Woke up without a hangover, got called off jury duty & @MixedInKeyjust came out with version 5.0 that analyzes video!!! Start of a good day

@MixedInKey You guys did it! #MIK5 is working like a charm. Gorgeous interface, unrivaled speed, heaps new features and still easy to use!!

My new @MixedInKey purchase rocks! Firing on all 4 cores at the moment at 100% CPU, this thing is #fast! Currently scanning 3000 songs :)

@MixedInKey is very very fast! Like a thunder! The multicore processing is the best feature

So Congratulations to Yakov and the rest of the Mixed In Key team, and thanks for letting me help out on such an exciting project.

Friday, 16 September 2011

Windows Runtime – Dial in the right expectations before reading up

Three days on from the announcement of the Windows Runtime at Microsoft’s Build conference the marketing dust is settling and the full picture emerging. As you begin to read up what the Windows Runtime actually is you’ll need to set your expectations to the right level or you run the risk of being disappointed. But set them appropriately and I think you’ll see that an exciting developer journey lies ahead.

Leading up to the conference I was hoping for a new lean-and-mean User Interface platform for writing any kind of Windows application. But that isn’t what Windows Runtime is about. As things stand this week, Windows Runtime is about producing Metro-style applications (think Windows Phone 7) optimised for running on Tablet devices. Windows Runtime is aimed squarely at the solar plexus of iOS and Android 3.0.

Miguel de Icaza and Tim Anderson have already done a good job of writing up what has been announced so far about Windows Runtime (or WinRT). But here are the two key points to notice:

  • Metro-style apps run in a sandboxed environment. As with Windows Phone 7, apps have to declare upfront, through a manifest built in at compilation time, which capabilities of your PC they intend to use. Access to APIs is monitored at runtime by the Runtime Broker, which prevents your app from doing anything naughty. Only certain parts of the .Net Base Class Libraries can be used, and even native developers are limited as to which Win32 or COM objects they call. Apps can only talk to each other through the WinRT-endorsed Contracts, which allow for Sharing, File-picking etc.

    To a developer all this sounds like a horrible restriction. But it is wonderful for users, who can have much more confidence that applications they install from the new App Store will not get up to mischief.

  • Metro-style apps are always full screen and immersive. Windows Runtime does not provide a general-purpose windowing system. Several presenters at the conference mentioned that support for overlapping windows have been intentionally left out. And for one simple reason: they don’t work well in a touch-centric environment.

Windows Runtime is not (at the moment) a general purpose runtime. It may get there eventually, but for the time being it is focused on building the kinds of apps and games that today you might run on the iPad, the Xoom, or (once the lawyers have finished their fisticuffs) the Galaxy Tab. Think of it as Silverlight-on-Steroids-With-Native-Extensions for Tablets and you won’t go far wrong.

As speakers at Build conceded, there are many kinds of application that would not fit the Metro-style. Visual Studio is one. Photoshop is another. Microsoft Office is (possibly) a third. For these kinds of apps, keyboard, mouse, menus, toolbars, ribbons and dialog boxes still works best.

This means Win32 and WPF are still very much alive. Though there are no sessions about it at the conference, WPF 4.5 has been announced with a number of not-insignificant new features, including the promised fix for the Win32 airspace restrictions (though nothing has been said about hosting Silverlight controls in WPF apps).

I’m no prophet, but I don’t believe this is the last we’ll hear about WPF.

Wednesday, 7 September 2011

Microsoft’s Build Windows Conference is Next Week – What’s in Store?

It’s less than a week to go until Microsoft’s Build conference. According to tradition, about now I should be speculating on what the future holds for us faithful Microsoft developers. But there’s still no official session list. Fortunately, we do have a few official hints, and a couple of very unofficial leaks to whet our appetites for what’s in store.

Windows 8

Read the Build homepage, and you’ll see that the conference is focused very clearly on Windows 8. We’ve already had a preview of the new touch-centric, Windows Phone 7-like UI. And over on the Building 8 blog, Steven Sinofsky and others on the Windows team have started announcing some of the to-be-expected features like USB 3.0 support.

Here are some of the other things that we know already:

And now comes the controversial part. Those of you who have not entirely delegated their memories to Google will recall that when Microsoft first showed the new Metro desktop for Windows 8, they announced that developers would be able to use HTML5 and JavaScript for building these new-fangled immersive apps. But they said nothing about the presence of .Net, WPF or Silverlight in this brave new world, stirring up an instant furore in the blogosphere.

But there’s no need to panic. It’s all under control. I think.

Direct UI

This is where we turn to the leaks. Leaked Windows 8 builds, that is.

According to Peter Bright over on Ars Technica, Microsoft are creating a new Windows Runtime (or WinRT), which is intended to be the successor to the Win32 API. It will be a native-code API, but shaped in a way that is pleasing to the eye of a managed-code developer, and what is more, said .Net developers will be able to access WinRT through a new (hopefully painless) version of COM for which support is being built into .Net 4.5.

Included in WinRT is a new UI framework called Direct UI which appears to be a lean-and-mean version of WPF/Silverlight (and also uses XAML – remember how part of the XAML team got moved to the Windows division!). With the official details coming out in less than a week, there’s little point on me elaborating further here, but you can get a taster of the new APIs by reading these two forum threads which dissect some of the leaked Windows 8 builds.

What I look forward to hearing is where WPF fits into the picture. One thing we know with a high degree of confidence, given Microsoft’s backwards-compatibility track record: current WPF applications will continue to work. The question is: will there be further development to WPF? As I reported last year, we know there are some new features coming, including fixing the airspace issues when hosting Hwnds inside WPF controls, and enabling hosting of Silverlight controls. But will there be anything beyond that? And will there be interop between WPF and Direct UI? Watch this space.

Silverlight

Remember that Microsoft stirred up another firestorm at PDC 2010 by staying mum about Silverlight? They put that right a few weeks later by announcing Silverlight 5, which was quite distinctly not a maintenance release, since it included a whole raft of new features like a 3d API, vector printing support, and P/Invoke for Trusted Applications. They’ve now made good on that, with the Silverlight 5 Release Candidate coming out just last week. It will be interesting to learn Microsoft’s vision for how Silverlight, WPF and Direct UI align.

C# 5.0

We already know the headline feature for C# 5: asynchronous methods. We’ve had a CTP. Here’s hoping for a beta release during the conference. One thing Anders did say at his talk last year is that async won’t be the only new feature in C# 5.0. So I wonder what else he has up his sleeves? It would be nice if it was the Roslyn project (Compiler as a Service).

Visual Studio

It sounds like Microsoft are preparing to release a new preview build of Visual Studio at Build. Many of the features that were previously released as PowerToys for VS 2010 are going to part of vNext. But the more interesting news to me is that Microsoft have been taking note of data coming back from PerfWatson to make some big performance improvements. Visual Studio vNext is going to make more use of multi-core machines, and will reduce memory usage in some cases by doing builds out-of-process for C# projects.

Stay Tuned

My new boss has kindly given me some time next week to follow the Build conference from the comfort of my office. And as in previous years, I’ll be reporting back the choicest titbits as I find them. Follow me on twitter to hear it as it happens.

Now, over to you. What are you looking forward to? Have you heard any rumours that I’ve not picked up on?

Tuesday, 12 July 2011

How to create Inner Shadow Effects in WPF and Silverlight

A new experience for me this week: I was handed a Photoshop file containing the new UI design for the app I’m currently working on, and asked to implement it in WPF. Easy, I thought: Expression Blend has a Photoshop Import feature.

Not so fast!

Whilst Blend does a pretty good job of importing simple Photoshop files, it struggles when asked to convert the little flourishes with which designers like to top off their masterpieces. Like inner shadows.

Thus the inspiration for another first: my first ever Code Project article, Creating Inner Shadow Effects for WPF and Silverlight, which went live this afternoon.

image

If you’ve ever wanted to render something like this in WPF, go read the article.

Tuesday, 21 June 2011

WPF Training, anyone?

The team over at Framework Training approached me recently about putting together a training course for WPF and possibly UI Automation. I’ve been giving it some thought, but I need your help.

What would you like to see in a WPF course? Or perhaps, more to the point, what do you think your non-blog-reading colleagues would benefit from hearing about? Are there any areas you can think of that are not covered by existing courses?

I’m guessing that the world doesn’t need another WPF 101. But people might like some help on more advanced topics, such as using the MVVM pattern, extending the declarative powers of WPF with Triggers and Behaviors, or even learning how to write robust tests against their UI using the UIAutomation API.

So, over to you. The comment box is open … now!

And if you think the world doesn’t need another WPF training course, tell me what you would like to see. And feel free to give me the benefit of your wisdom on how training course in general should or should not be run.

Perhaps an incentive would help you put fingers to keyboard? I’ll give a £25 Amazon voucher to the person who (in my judgement) leaves the most helpful suggestions.

Update: My thanks (and, more concretely, a £25 gift voucher!) go to Jedrzej Sztompka who emailed in a copious list of suggestions. But don’t let that put you off: I’ll keep the offer open for anybody else who gets in touch with significant useful ideas.

Thursday, 16 June 2011

Resharper 6 XAML Tip: Intellisense for your Databindings

Anybody who has installed the Resharper 6 Beta (and that should be all of you – it’s awesome, and no major problems that I can see) will find in it a feature I’ve been wanting ever since WPF was first released: intellisense for databindings.

Mark up your Xaml so that Resharper knows the type of your DataContext and it will tell you what properties you can bind to, and warn you if it doesn’t recognize what you’ve typed. I’m always switching back and forth between my Views and ViewModels to make sure I get my property names right, so this will be a real time-saver.

There are lots of places where Resharper can already deduce the type of the DataContext – within DataTemplates where you’ve specified a DataType, for example. In other cases, there's just one thing you have to do to enable this awesome feature.

At the root of your file, you need to add the d:DataContext attribute and set it to the type of you Datacontext. Here’s an example:

<UserControl x:Class="MyApp.Views.MyView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:ViewModels="clr-namespace:MyApp.ViewModels"
             mc:Ignorable="d"
             d:DataContext="{d:DesignInstance ViewModels:MyViewModel, IsDesignTimeCreatable=False}">

Now if you press Ctrl-Space within a binding element, you’ll get lovely intellisense:

image

Friday, 4 February 2011

Multiplayer-enabling my Windows Phone 7 game: Day 2–Building a UI with XPF

I’m building a game to enter in Red Gate’s Windows Phone 7 App competition. The first challenge I set myself was to build the core of the game in 3 days from a standing start. Then Red Gate moved the goal posts. So I’ve set myself a new challenge: make the game multi-player in 3 days, using Windows Azure for the server side.  Day 1, was spent getting up to speed with Windows Azure and networking on WP7. Here’s Day 2:

9:00 Decided to take the plunge and go with Red Badger's XPF framework for the UI - what else can I do, if I want to get this thing done in three days? I’m going to need TextBoxes, ListBoxes and the like, and I certainly wouldn’t be able to write them from scratch in the time I have. On Red Badger’s roadmap, there’s no word on a likely release date. I wonder if I can badger them into at least giving me a build that won’t expire before the competition gets judged?

9:43 Got my first "Hello World" screen working using XPF. For ages I couldn't get buttons to respond to clicks, until I noticed from a sample that I needed to supply an InputManager instance to the RootElement.

10:47 Created a TextBox control using XPF. They've done a good job of mimicking the Silverlight API. And in some ways, their DependencyProperty implementation is even better! It uses generics for a start. And the key classes are actually called ReactiveProperty and ReactiveObject because their change notification is based on IObservable from the Rx Framework (which, by the way, comes in the box on WP7). Text input on XNA is pretty limited. Your only option is to call Guide.BeginShowKeyboardInput, which is an async method that takes care of showing the soft keyboard as well as the editor, and then returns to you the text that was entered.

11:40 Refactored my game so it now has Screen classes to represent the states that it can be in - Showing the Game, Showing the Welcome Screen, Showing Help, etc. It’s nice that XNA has the concept of Components and Services built in.

14:21Got a simple dialog working:

clip_image001

14:36 Borrowed the Messenger code from Laurent Bugnion's MVVM Light Toolkit to enable me to pass messages in a loosely coupled way between my screens.

15:06 Seeing strange behaviour in XPF where clicks on a button seem to be handled twice: once by the button, and then by widgets on the following screen (which is made visible by the button click). Realise that this is what comes of changing one screen for another in the middle of handling events. I'm going to have to implement a mini message queue so I can queue the change of screen after the button event has been handled.

15:15 Implemented the message queue, and magically another bug goes away too! That bug was most odd – after I clicked one button, moved to a different screen, then moved back again, all the other buttons would stop working. It turned out that the first button was capturing the mouse events, so the other buttons didn’t get a look in. Making sure that events completed before changing screens obviously fixed the mouse capture problem too.

16:05 Dialogs are coming on nicely now, but it sure is tedious building up a control hierarchy in C#. Oh XAML, how I miss you!

17:21 Got a very basic ListBox working on top of XPF. The time I’ve spent delving around in WPF and Silverlight certainly helps out here!

image

17:30 I think that’s enough of the multi-player UI done for now. That leaves me with one day to implement the multi-player logic, and the server.

Do you think I can do it?

Tuesday, 25 January 2011

A FindResource implementation for Silverlight

Here’s an interesting omission in Silverlight that I stumbled upon today: Silverlight doesn’t provide you with a way to do a hierarchical resource look-up in code.

You can do it in XAML. Write

<Grid>
    <Grid.Resources>
        <Style x:Key="MyStyle>
        </Style>
    </Grid.Resources>
    <DockPanel>
        <Button>
            <TextBlock Style="{StaticResource MyStyle}"/>
        </Button>
    </DockPanel>
</Grid>

and the TextBlock will find the appropriate style in the Grid’s resource dictionary, even though it’s several layers up the hierarchy. And if the resource isn’t found in any of the parent elements, StaticResource will then look in the Application’s Resource Dictionary.

But, whereas WPF provides the TryFindResource method to do the same kind of look-up in code, the best you can do in Silverlight is

element.ResourceDictionary[“MyStyle”]
and that returns null if the resource isn’t in the element’s own ResourceDictionary. 

No matter. It’s easy to a proper lookup yourself:

public static class FrameworkElementExtensions
{
    public static object TryFindResource(this FrameworkElement element, object resourceKey)
    {
        var currentElement = element;

        while (currentElement != null)
        {
            var resource = currentElement.Resources[resourceKey];
            if (resource != null)
            {
                return resource;
            }

            currentElement = currentElement.Parent as FrameworkElement;
        }

        return Application.Current.Resources[resourceKey];
    }
}

With that in place

textBox.TryFindResource("MyStyle");
will do what you expect.

Which of course makes me wonder why this was omitted from Silverlight in the first place. Am I missing something?

Monday, 1 November 2010

WPF to support hosting of Silverlight controls in vNext

To the great consternation of the blogosphere, Joe Stegman’s planned session on Silverlight quietly disappeared from the Microsoft PDC schedule, and no new announcements were made on that front. Instead we got a pre-recorded session from Rob Relyea entitled WPF Today and Tomorrow.

Microsoft adoption

Early on in his talk Rob reminded us that Microsoft is making the ultimate commitment to WPF in that many of their latest products are built on it, including the Expression Studio suite, Visual Studio, and most recently Web Matrix [see the demo in Rob’s talk]. He also hinted that there are other products on the way which cannot be announced yet.

As part of these efforts across Microsoft a number of controls have been developed which Rob feels would be widely applicable(one of which is WPF equivalent of the Silverlight ChildWindow) and he intends to work with the respective teams to release these components to the web.

Silverlight Integration

One welcome announcement Rob made was that the next version of WPF will support hosting of Silverlight controls [watch his demo]. Today, of course, this is somewhat possible by hosting a Web Browser inside WPF, then navigating it to some Silverlight content. What Rob announced was something deeper than that, in two ways. The first is that they want to enable good communication between the WPF host and the Silverlight components, including sharing data.

The second improvement was part of a bigger announcement: they are planning to solve the airspace issues with hosting embedded Hwnd content [watch]. This was something I didn’t expect – in fact, I thought the airspace issue was a problem here to stay.

To briefly recap what the airspace issue is: in current versions of WPF, whenever you need to embed Win32-based content inside WPF, the embedded content always ends up sitting on top of the WPF stuff. This is because Win32 Hwnds don’t layer well with WPF elements – they can’t share airspace. You also can’t rotate or scale the Hwnds or adjust their opacity like you can with WPF elements.

Rob announced that Microsoft will be making a large investment, and will remove the airspace restrictions. And I can see why it will be a large investment. From what Rob said [watch] it seems that they way they plan to tackle this is by rendering Hwnds off-screen so that their visuals can be composited into the appropriate place in the visual tree, then any keyboard our mouse input intended for the control will have to be redirected from the WPF surface back to the Hwnd. A tough challenge indeed – but with great rewards for anybody looking to port legacy applications.

Amongst other things that Microsoft are considering for WPF vNext, Rob mentioned the following:

  • Proper support for Grouping in ItemsControls when doing UI Virtualization [watch]
  • Improved support for data-binding to collections and properties that get updated in a background thread [watch]. For collections, this will involve adding APIs to allow the data-binding engine to interact with the locking scheme used in the collection.

Thursday, 7 October 2010

Getting started with Protocol Buffers – and introducing Protocol Buffers Workbench

So I’ve fallen out of love with Xml, and decided that Google Protocol Buffers is a better serialization format for a key (and voluminous) data structure in our application (as has Twitter, incidentally). For various reasons, I decided to write my own Reader and Writer rather than go with the existing implementations. The first thing I needed to do then, was to understand how the Protocol Buffers encoding works.

Google have published some very good documentation, both for the message definition language, and the encoding, but nothing beats seeing it in action. For that there’s a Protocol Buffers compiler, protoc.exe which, amongst other things, will handle encoding and decoding messages (get it from the Protocol Buffers website - choose “Protocol Buffers compiler – Windows Binary”). The only thing is, protoc.exe is a command-line tool, and not very friendly if you’re just wanting to fiddle around. So I’ve summoned all my WPF powers, and created a graphical wrapper around it. Allow me to introduce Protocol Buffers Workbench:

image

In brief

Using the Workbench is easy:

  1. Install it using the ClickOnce installer.
  2. Put your message definition in the first column, and, from the drop-down pick the message that will be at the root of your document
  3. Enter your message in the second column, then hit the encode button (“>”). The encoded message is shown in the third column.

Or, if you have an encoded message, you can paste it into the third column and hit decode (“<”) to have the message translated into text format. The Paste button above the third column is particularly useful if you want to decode protocol buffers messages stored in binary columns in Sql Server. If you view such columns in Sql Management Studio they are displayed like “0x0A1B2C4D…”: the Paste button will recognise text in the clipboard in that format and paste it as binary data.

If you’re wondering about the “C#” toggle beneath the binary editor: that will encode the binary data as a C# byte array – particularly useful if you’re wanting to seed your unit tests with authentic protocol buffer bytes!

And that’s it. Unless you want to know more about defining message types, and writing messages in text message format – in which case, read on.

Message Types

The first thing to understand are the message types. Message types are a bit like an Xml Schema. But whereas you can understand Xml just fine without a Schema, having the message types to hand is essential when parsing a Protocol Buffers message. That's because, in a bid to squeeze the output as small as possible, all the wordy field identifiers and even field type information is stripped out. All that's left for each piece of data is a field number, and a few bits telling you how big it is.

Message types look like this:

enum Binding { 
   PAPERBACK = 1;
   HARDBACK = 2;
} 
 
message Author { 
   required string name = 1; 
   optional string location = 2; 
} 
 
message Book { 
   required string title = 1; 
   required Binding binding = 2; 
   repeated Author author = 3; 
   optional int32 number_of_pages = 4; 
   optional double weight = 5; 
}

So for each field in a message, you define if it must be present ("required"), it may be present ("optional"), or if it can appear any number of times, including never ("repeated"). You then give its type - and you have a range to choose from, including enums and your own custom message types. Finally, you assign it a field number: this is the critical part, as this is all that will distinguish between the different pieces of data in the resulting messages.

Messages in Text Message Format

It took me a bit of puzzling to work out how to write messages in text format. For some reason, though Google have defined a text format for Protocol Buffer Messages, they don't appear to have documented it any where.

Here's an example, using the message types defined above:

title: "The Holy Bible"
binding: HARDBACK
author: {
  name: "Moses"
  location: "Sinai Peninsula"
}
author: {
   name: "Paul"
   location: "Tarsus"
}
author: {
   name: "Luke"
}
number_of_pages: 1723
weight: 0.225

As you can see, it has some similarities to JSON, but not many. Field names aren’t enclosed in strings, for example, and they aren’t terminated by commas.

Friday, 25 June 2010

WPF MVVM Commands - new reduced-boilerplate recipe

Morgan Skinner, an Application Development Consultant with Microsoft UK, had a post on his blog yesterday complaining at the quantity of boilerplate code needed to create commands in ViewModels for WPF and Silverlight. I share his irk about that.

He shows a clever technique involving ICustomTypeDescriptor that avoids creating properties (and hence backing fields) for each of the commands. But I think he goes too far. Without the properties on the ViewModel, its tests are going to have a hard time knowing what commands it exposes; and accessing them through code isn’t going to be as straightforward as a property access.

So I propose an alternative technique. It boils down to this:

public class MyViewModel : ViewModelBase
{
    public ICommand Demonstrate
    {
        get
        {
            return Commands.GetOrCreateCommand(
                () => this.Demonstrate,
                DoDemonstration,
                IsFeelingDemonstrative);
        }
    }

    private void DoDemonstration()
    {
        MessageBox.Show("Ta da!");
    }

    private bool IsFeelingDemonstrative()
    {
        return DateTime.Today.DayOfWeek == DayOfWeek.Friday;
    }
}

As you can see, ViewModelBase is providing a Commands property to manage all the commands. This neatly avoids having to create a field for each one. Commands is an instance of CommandHolder which is equally simple:

public class ViewModelBase : INotifyPropertyChanged
{
    CommandHolder _commandHolder = new CommandHolder();

    // snipped Property Change stuff

    protected CommandHolder Commands
    {
        get
        {
            return (_commandHolder ?? (_commandHolder = new CommandHolder()));
        }
    }
}
public class CommandHolder
{
    Dictionary<string, ICommand> _commands = new Dictionary<string, ICommand>();

    public ICommand GetOrCreateCommand<T>(
        Expression<Func<T>> commandNameExpression, 
        Action executeCommandAction, 
        Func<bool> canExecutePredicate)
    {
        return GetOrCreateCommand(
            commandNameExpression,
            parameter => executeCommandAction(),
            parameter => canExecutePredicate());    
    }

    public ICommand GetOrCreateCommand<T>(
        Expression<Func<T>> commandNameExpression, 
        Action<object> executeCommandAction, 
        Func<object, bool> canExecutePredicate)
    {
        var commandName = SymbolHelpers.GetPropertyName(commandNameExpression);

        if (!_commands.ContainsKey(commandName))
        {
            var command = new DelegateCommand(executeCommandAction, canExecutePredicate);
            _commands.Add(commandName, command);
        }

        return _commands[commandName];
    }
}

What do you think? Are my concerns about testa-reada-bility warranted? Does my technique eliminate enough of the boilerplate?

I’ve put a full sample on MSDN code gallery.

Thursday, 31 December 2009

Specifying Resource Keys using Data Binding in WPF, Take 2: Introducing the ResourceKeyBinding markup extension

A few nights before Christmas, when, all through the house, not a distraction was stirring, not even a spouse, I posted about a technique that mixed up Resources and Data Binding in WPF, letting you use data binding to specify the key of the resource you wanted to use for a property. This trick helps to keep ViewModels unpolluted by Viewish things such as the URIs of images, while still retaining some control of those aspects - for example, over which Images are shown.

There was one thing I didn’t like about the technique that I showed: for every kind of Dependency Property that was to be the target of a data-bound resource key, you had to use my ResourceKeyBindingPropertyFactory to derive a new Dependency Property to hold the data binding.

Today I’m going to show a much more elegant technique: the ResourceKeyBinding markup extension. In the following snippet, I’ve modified the example I showed last time so that it now uses my new ResourceKeyBinding to data bind the keys of the resources used for the caption on the buttons:

<DataTemplate>
  <Button Command="{Binding}" Padding="2" Margin="2" Width="100" Height="100">
    <StackPanel>
      <Image HorizontalAlignment="Center"
             Width="60"
             app:ResourceKeyBindings.SourceResourceKeyBinding="{Binding Converter={StaticResource ResourceKeyConverter}, ConverterParameter=Image.{0}}"/>
      <TextBlock Text="{ext:ResourceKeyBinding Path=Name, StringFormat=Caption.{0} }" HorizontalAlignment="Center" FontWeight="Bold" Margin="0,2,0,0"/>
    </StackPanel>
  </Button>
</DataTemplate>

As you can see from line 7, you use ResourceKeyBinding in almost exactly the same way that you would use a normal Binding: not shown here are Source, RelativeSource or Element properties that work as you would expect; and, as per Binding, if all of these are omitted, the data source for the ResourceKeyBinding is the DataContext of the element. I’m also making use of the StringFormat capability of data bindings, which gets the value of the property indicated by Path and applies the given string format to it.

With this in place, the TextBlock should be given the appropriate value picked out from our amended App.xaml:

<Application.Resources>
  <BitmapImage x:Key="Image.AngryCommand" UriSource="Angry.png"/>
  <BitmapImage x:Key="Image.CoolCommand" UriSource="Cool.png"/>
  <BitmapImage x:Key="Image.HappyCommand" UriSource="Happy.png"/>

  <sys:String x:Key="Caption.Angry">Angry. Rrrr!</sys:String>
  <sys:String x:Key="Caption.Happy">Happy. Ha ha!</sys:String>
  <sys:String x:Key="Caption.Cool">Chilled out</sys:String>
</Application.Resources>

And sure enough, it is:

ResourceBindingSampleImage2

Behind the curtain

So how does it work? There are two parts to it. The first component is the markup extension itself:

public class ResourceKeyBindingExtension : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var resourceKeyBinding = new Binding()
        {
            BindsDirectlyToSource = BindsDirectlyToSource,
            Mode = BindingMode.OneWay,
            Path = Path,
            XPath = XPath,
        };

        //Binding throws an InvalidOperationException if we try setting all three
        // of the following properties simultaneously: thus make sure we only set one
        if (ElementName != null)
        {
            resourceKeyBinding.ElementName = ElementName;
        }
        else if (RelativeSource != null)
        {
            resourceKeyBinding.RelativeSource = RelativeSource;
        }
        else if (Source != null)
        {
            resourceKeyBinding.Source = Source;
        }

        var targetElementBinding = new Binding();
        targetElementBinding.RelativeSource = new RelativeSource()
        {
            Mode = RelativeSourceMode.Self
        };

        var multiBinding = new MultiBinding();
        multiBinding.Bindings.Add(targetElementBinding);
        multiBinding.Bindings.Add(resourceKeyBinding);

        // If we set the Converter on resourceKeyBinding then, for some reason,
        // MultiBinding wants it to produce a value matching the Target Type of the MultiBinding
        // When it doesn't, it throws a wobbly and passes DependencyProperty.UnsetValue through
        // to our MultiBinding ValueConverter. To circumvent this, we do the value conversion ourselves.
        // See http://social.msdn.microsoft.com/forums/en-US/wpf/thread/af4a19b4-6617-4a25-9a61-ee47f4b67e3b
        multiBinding.Converter = new ResourceKeyToResourceConverter()
        {
            ResourceKeyConverter = Converter,
            ConverterParameter = ConverterParameter,
            StringFormat = StringFormat,
        };

        return multiBinding.ProvideValue(serviceProvider);
    }

    [DefaultValue("")]
    public PropertyPath Path { get; set; }

    // [snipped rather uninteresting declarations for all the other properties]
}

Under the covers, ResourceKeyBindingExtension is being rather cunning. It constructs a MultiBinding with two child bindings: one binding is used to get hold of the resource key: this is initialised with the parameters that ResourceKeyBinding is given – the property path and data source, for example. The other child binding is set up with a RelativeSource mode of Self so that it grabs a reference to the ultimate target element (in the case of the example above, the TextBlock).

Every MultiBinding needs a converter, and we configure ours in line 45. The job of this converter is to use the resource key obtained by the second child binding to find the appropriate resource in the pool of resources available to the target element obtained by the first child binding – FrameworkElement.TryFindResource does the heavy lifting for us here:

class ResourceKeyToResourceConverter : IMultiValueConverter
{
    // expects the target object as the first parameter, and the resource key as the second
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values.Length < 2)
        {
            return null;
        }

        var element = values[0] as FrameworkElement;
        var resourceKey = values[1];
        if (ResourceKeyConverter != null)
        {
            resourceKey = ResourceKeyConverter.Convert(resourceKey, targetType, ConverterParameter, culture);
        }
        else if (StringFormat != null && resourceKey is string)
        {
            resourceKey = string.Format(StringFormat, resourceKey);
        }

        var resource = element.TryFindResource(resourceKey);

        return resource;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public IValueConverter ResourceKeyConverter { get; set; }

    public object ConverterParameter { get;set;}

    public string StringFormat { get; set; }
}

You’ll notice that if ResourceKeyBinding is given a Converter or a StringFormat it doesn’t give these to resourceKeyBinding as you might expect. Instead it passes them on to the ResourceKeyToResourceConverter, which handles the conversion or string formatting itself. I’ve not done it this way just for fun: I found out the hard way that if you include a converter in any of the child Bindings of a MultiBinding, then WPF, rather unreasonably in my opinion, expects that converter to produce a result that is of the same Type as the property that the MultiBinding is targeting. If the Converter on the child Binding produces a result of some other type, then the MultiBinding passes DependencyProperty.UnsetValue to its converter rather than that result. There’s a forum thread discussing this behaviour but no real answer as to whether this is by design or a bug.

Watch this bug don’t getcha

One other gotcha with custom markup extensions, this one definitely a bug in Visual Studio. If you define a custom markup extension, and then, in Xaml that is part of the same assembly, you set one of the properties of that markup extension using a StaticResource you’ll get a compile-time error similar to:

Unknown property '***' for type 'MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension' encountered while parsing a Markup Extension.

The workaround, as Clint discovered, is either to put your markup extension in a separate assembly (which is what I’ve done) or use Property Element syntax for the markup extension in XAML.

Try it yourself

I’ve updated the code on the MSDN Code Gallery page – go see if for yourself.

Wednesday, 23 December 2009

Specifying Resource Keys using Data Binding in WPF

Imagine you’re wanting to show a list of things in an ItemsControl, with each item having a different image. Using WPF’s implicit Data Templating support, and giving each item Type its own Data Template is one way of implementing this: but if there are many items, and the image is the only thing that’s different in each case, and the Data Template is of any complexity, your code will soon start to suffer DRY rot.

You could just pinch your nose and put the image in your ViewModel so that it can be databound in the normal way. Of course, images should really live in a ResourceDictionary: but how can you pick a resource out of a ResourceDictionary using data binding? Let me show you.

The example: AutoTherapist

Here’s what I want to build:ResourceBindingSampleImage

I’ve got a very simple ViewModel with a property exposing a list of the commands that sit behind the buttons in my Window:

public class WindowViewModel
{
    public IList<ICommand> Commands
    {
        get
        {
            return new ICommand[] { new AngryCommand(), new HappyCommand(), new CoolCommand() };
        }
    }
}

And here’s the relevant part of the View:

<ItemsControl Grid.Row="1" ItemsSource="{Binding Commands}">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Button Command="{Binding}" Padding="2" Margin="2" Width="100" Height="100">
          <StackPanel>
            <Image HorizontalAlignment="Center"
                   Width="60"
                   app:ResourceKeyBindings.SourceResourceKeyBinding="{Binding Converter={StaticResource ResourceKeyConverter}, ConverterParameter=Image.{0}}"/>
            <TextBlock Text="{Binding Name}" HorizontalAlignment="Center" FontWeight="Bold" Margin="0,2,0,0"/>
          </StackPanel>
        </Button>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

The ItemsControl is bound to the Commands property on my ViewModel. Each command is rendered with the same DataTemplate. The magic happens in line 8 where I’m using the attached property ResourceKeyBindings.SourceResourceKeyBinding. This property allows me to data-bind the key of the resource I want to use for the Image.Source property. I’ll show you how that works in a minute, but first: where are the resource keys coming from?

You’ll notice that, since there’s no Path specified in the Binding, we’re binding directly to the data object - in this case, one of the commands. Then we’re using a converter to turn that object into the appropriate key. Here’s the code for the converter:

class TypeToResourceKeyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var formatString = parameter as string;
        var type = value.GetType();
        var typeName = type.Name;

        var result = string.Format(formatString, typeName);

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

What this is doing is getting the name of the Type of the data object and pushing that through the format string given as the parameter to the converter. Given the way the converter is set up in our case, this will produce resource keys like “Image.AngryCommand”, “Image.HappyCommand”, etc.

So now all we need to make the AutoTherapist work is to define those resources. Here’s App.xaml:

<Application x:Class="ResourceKeyBindingSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml">
    <Application.Resources>
      <BitmapImage x:Key="Image.AngryCommand" UriSource="Angry.png"/>
      <BitmapImage x:Key="Image.CoolCommand" UriSource="Cool.png"/>
      <BitmapImage x:Key="Image.HappyCommand" UriSource="Happy.png"/>
    </Application.Resources>
</Application>

(The icons are from VistaIcons.com, by the way).

The implementation

So what does that attached property look like? It’s actually rather simple:

public static class ResourceKeyBindings
{
    public static DependencyProperty SourceResourceKeyBindingProperty = ResourceKeyBindingPropertyFactory.CreateResourceKeyBindingProperty(
        Image.SourceProperty,
        typeof(ResourceKeyBindings));

    public static void SetSourceResourceKeyBinding(DependencyObject dp, object resourceKey)
    {
        dp.SetValue(SourceResourceKeyBindingProperty, resourceKey);
    }

    public static object GetSourceResourceKeyBinding(DependencyObject dp)
    {
        return dp.GetValue(SourceResourceKeyBindingProperty);
    }
}

As you can see, I’ve factored out the magic into ResourceKeyBindingPropertyFactory. This makes it easy to create equivalent properties for any other target property (in the download, for example, I’ve made a StyleResourceKeyBinding property for binding to FrameworkElement.Style). ResourceKeyBindingPropertyFactory looks like this:

public static class ResourceKeyBindingPropertyFactory
{
     public static DependencyProperty CreateResourceKeyBindingProperty(DependencyProperty boundProperty, Type ownerClass)
     {
         var property = DependencyProperty.RegisterAttached(
             boundProperty.Name + "ResourceKeyBinding",
             typeof(object),
             ownerClass,
             new PropertyMetadata(null, (dp, e) =>
             {
                 var element = dp as FrameworkElement;
                 if (element == null)
                 {
                     return;
                 }

                 element.SetResourceReference(boundProperty, e.NewValue);
             }));

         return property;
     }
}

All we do here is register an attached property and set it up with a PropertyChanged handler: the handler simply takes the new value of the property – which in our case will be the resource key – and passes it to SetResourceReference along with the target property. SetResourceReference is the programmatic equivalent of using DynamicResource in XAML – it looks up the appropriate resource (from the current element’s ResourceDictionary or one of its ancestors’) and assigns it to the given property.

So there you have it: data binding for Resource Keys. Full source code for this sample is available from the MSDN Code Gallery.

Not for Silverlight

Unfortunately I don’t think it is possible to port this to Silverlight without a lot of work because Silverlight has no support for Dynamic Resources. From a cursory look, I don’t think there is even runtime support built in for finding a Resource in the Resource Dictionary chain up the ancestor tree of an element as there is in WPF: it looks like the Silverlight parser is responsible for doing this when required by StaticResource references. I would be delighted if someone could show me otherwise

Thursday, 12 November 2009

PDC 2009 @ Home

Can you believe it? A year flown by already since I jetted off to LA, reclined to the soothing sound of Scott Gu's Keynote, and all-round indulged in a general geek-out at Microsoft PDC 2008! And already Microsoft PDC 2009 is upon us.

Windows 7, which we gawped at for the first time twelve months ago, is now gracing our desktops; Windows Azure is almost ready to go live; and after a good 52 weeks of head-scratching developers are just beginning to work out what Oslo is and isn't good for.

What with our baby being born and Bankers busting our economy, I'm not going to be present in person at the PDC this year. But the Directors at Paragon have very kindly granted us all a couple of days to be present in spirit by taking advantage of the session videos that Microsoft generously post online within 24 hours of the event.

So which sessions will I be watching?

Top of my list are the PDC specialties, the sessions usually flagged up with the magic word "Future" in their title. What developer doesn't go to PDC with an ear greedy for announcements of shiny new features for their favourite platform?

The other thing PDC is famous for are “deep-dives”: talks by the architects and developers of the various technologies on show, laying bare the inner workings of their creations. This year I’ll probably focus on WPF and Silverlight.

As well as watching these sessions, I hope to find some time over the next week for blogging about my discoveries. So why don’t you follow along?

Friday, 2 October 2009

Work around for WPF Bug: Drag and Drop does not work when executing a WPF application in a non-default AppDomain

Today's task was implementing Drag/Drop to move items into folders. My estimate of yesterday was 6 hours to get the job done. That should have been plenty: then I discovered the bug.

We're creating an Excel Addin using Addin-Express (which is very like VSTO). All the UI for our add-in is built with WPF (naturally). When Addin Express hosts Add-ins for Excel, it isolates them each in their own App-Domain. Which is why today I came to add myself to the list of people who have reproduced this issue on the Connect website: "Drag and Drop does not work when executing a WPF application in a non-default AppDomain"

Googling around the problem, I found that Tao Wen had also encountered the problem, and had managed to find something of a work-around.

Having Reflectored around the WPF source-code a little, I can see that when WPF is hosted in a non-default App Domain, the check that the HwndSource class (which manages the Win32 Window object on behalf of the WPF Window class) does to ensure the code has the UnmanagedCode permission fails, so Windows do not register themselves as OLE Drop Targets (see the last few lines of the HwndSource.Initialize method)

Tao Wen's solution is to use reflection to directly call the internal DragDrop.RegisterDropTarget method. What his solution doesn't take into account is that, when the Window is closed it must unregister itself as a drop target.

Fortunately, by incrementing the _registeredDropTargetCount field in the HwndSource class we can ensure that HwndSource will itself call DropDrop.RevokeDropTarget when it's disposed (see about half-way down the HwndSource.Dispose method).

For anybody else who is blocked by the same issue, I've created a little class that will implement the hack on a Window class. Be warned: it uses evil reflection code to access private members of WPF classes, and it might break at any time. Use it at your own risk.

/// <summary>
/// Contains a helper method to enable a window as a drop target.
/// </summary>
public static class DropTargetEnabler
{
    /// <summary>
    /// Enables the window as drop target. Should only be used to work around the bug that
    /// occurs when WPF is hosted in a non-default App Domain
    /// </summary>
    /// <param name="window">The window to enable.</param>
    /// <remarks>
    /// This is a hack, so should be used with caution. It might stop working in future versions of .Net.
    /// The original wpf bug report is here: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=422485
    /// </remarks>
    // This code was inspired by a post made by Tao Wen on the Add-in Express forum:
    // http://www.add-in-express.com/forum/read.php?FID=5&TID=2436
    public static void EnableWindowAsDropTarget(Window window)
    {
        window.Loaded += HandleWindowLoaded;
    }

    private static void HandleWindowLoaded(object sender, RoutedEventArgs e)
    {
        // See the HwndSource.Initialize method to see how it sets up a window as a Drop Target
        // also see the HwndSource.Dispose for how the window is removed as a drop target
        var window = sender as Window;

        IntPtr windowHandle = new WindowInteropHelper(window).Handle;

        // invoking RegisterDropTarget calls Ole32 RegisterDragDrop
        InvokeRegisterDropTarget(windowHandle);

        // to make sure RevokeDragDrop gets called we have to increment the private field
        // _registeredDropTargetCount on the HwndSource instance that the Window is attached to
        EnsureRevokeDropTargetGetsCalled(windowHandle);
    }

    private static void InvokeRegisterDropTarget(IntPtr windowHandle)
    {
        var registerDropTargetMethod = typeof(System.Windows.DragDrop)
            .GetMethod("RegisterDropTarget", BindingFlags.Static | BindingFlags.NonPublic);
        if (registerDropTargetMethod == null)
        {
            throw new InvalidOperationException("The EnableWindowAsDropTarget Hack no longer works!");
        }

        registerDropTargetMethod
            .Invoke(null, new object[] { windowHandle });
    }

    private static void EnsureRevokeDropTargetGetsCalled(IntPtr windowHandle)
    {
        var hwndSource = HwndSource.FromHwnd(windowHandle);
        var fieldInfo = typeof(HwndSource).GetField("_registeredDropTargetCount", BindingFlags.NonPublic | BindingFlags.Instance);
        if (fieldInfo == null)
        {
            throw new InvalidOperationException("The EnableWindowAsDropTarget hack no longer works!");
        }

        var currentValue = (int) fieldInfo.GetValue(hwndSource);
        fieldInfo.SetValue(hwndSource, currentValue + 1);
    }
}

Use it like this:

public partial class MyWindow
 {
        public MyWindow()
        {
            InitializeComponent();
            DropTargetEnabler.EnableWindowAsDropTarget(this);
        }
}

Thursday, 12 February 2009

How to Databind to a SelectedItems property in WPF

Many moons ago, I asked on the WPF forums if anybody had a way of data-binding the SelectedItems property of a ListBox. Standard data binding doesn’t work, because the SelectedItems property is read-only, and understandably so: how would you like it if I injected an arbitrary collection into your ListBox and expected you to keep it up to date as the selection changed?

As no one gave me an answer, I was forced to use my gray-matter and invent a solution of my own. Since a similar question came up again recently on Stack Overflow, I thought I’d share what I came up with.

In my solution, I define an attached property that you attach to a ListBox (or DataGrid, or anything that inherits from MultiSelector) and allows you to specify a collection (via data binding, of course) that you want to be kept in sync with the SelectedItems collection of the target. To work properly, the collection you give should implement INotifyCollectionChanged – using ObservableCollection<T> should do the trick. When you set the property, I instantiate another class of my invention, a TwoListSynchronizer. This listens to CollectionChanged events in both collections, and when either changes, it updates the other.

To help me demonstrate, I’ve knocked up a toy ViewModel: it has on it an AvailableNames property that will be the data source for the ListBox, a SelectedNames property which is the reason we’re going through the whole exercise, and a Summary property which displays the number of selected items to prove that the data binding is working correctly.  I won’t bore you with the code – see the download link below.

The XAML looks like this:

<Window x:Class="SelectedItemsBindingDemo.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="clr-namespace:SelectedItemsBindingDemo"
  xmlns:ff="clr-namespace:FunctionalFun.UI.Behaviours"
  Title="SelectedItems Binding Demo" Height="300" Width="300"
      >
<Window.DataContext>
  <d:ViewModel/>
</Window.DataContext>
  <Grid Margin="5">
    <Grid.RowDefinitions>
      <RowDefinition Height="*"/>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center"
               Text="{Binding Summary}" FontWeight="Bold" Margin ="0,5,5,5"/>
    <Button Content="Select All" Command="{Binding SelectAll}" Grid.Row="1"
            HorizontalAlignment="Right" VerticalAlignment="Center"/>
    <ListBox Grid.Row="0"
             ItemsSource="{Binding AvailableNames}"
             ff:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding SelectedNames}"
             SelectionMode="Extended" />
  </Grid>
</Window>

All the magic is initiated by line 22 where I set the attached property MultiSelectorBehaviours.SynchronizedSelectedItems using a data binding to my SelectedNames property. With that in place the SelectedNames collection in my ViewModel is updated whenever SelectedItems on the ListBox changes. And to prove it works the other way to, I’ve created a SelectAll command on the ViewModel that puts all available names into the SelectedNames collection. When you press the button you’ll see that the ListBox obediently updates to show all items selected.

The TwoListSynchronizer code does not make especially thrilling reading, so I won’t show it here. If you should peruse it however, there are a couple of things you might wonder about:

  • I’ve made it implement IWeakEventListener so that it can subscribe to CollectionChanged events using weak events. This means I don’t have to worry about creating managed memory leaks if the source SelectedItems collection has a longer lifetime than the ListBox.
  • The code occasionally refers to something called a IListItemConverter. I’m not make use of this in this application of the TwoListSynchronizer, but it might have uses elsewhere. The scenario I had in mind was where there is some kind of mapping between the items in the two collections that need to be synchronized.

Update (25/07/2013): All the code is now available on Github (under a Public Domain License). Download a zip file directly here.