Following RTM of Visual Studio 2010, Silverlight 4.0 and .NET Framework 4.0, we've update nRoute to target Silverlight 4 for the Web and .NET 4.0 for the desktop. Though the feature-set of the new release is essentially the same as the previous release, this is more than just a re-compiled version - we've tweaked the code to take advantage of the binding enhancements and the introduction of custom/predefined xml-namespaces in Silverlight 4.
Binding Enhancements
As you already know Silverlight 4 (SL4) significantly improves the binding story, gone are the limitations of only being able to bind to FrameworkElement derivates - we can now, in parity to WPF, bind to any Dependency Object. Taking advantage of this we've removed nRoute's custom binding infrastructure (though it remains for WP7) and lowered the barrier to entry for a lot of behaviors and triggers as we aren't anymore limited to inline FrameworkElements only.
One breaking but useful change we've made is to make Url parameters bindable - as you know when you effect navigation or controller-actions in nRoute you can optionally pass these key-value pairs of parameters, kind of like with form collection in HTML. However, earlier owing to the binding limitations of Silverlight you were limited to using statically declared parameters (or bind to the parameter's collection in its entirety) - but now with the binding enhancements we can simply bind against each parameter directly, see:
1: <Button Content="Customer Overview" Height="25" Width="100">
2: <i:Interaction.Triggers>
3: <i:EventTrigger EventName="Click">
4: <n:NavigateAction Url="Pages/Customer/Overview">
5: <n:DependencyParameter Key="Customer" Value="{Binding ActiveCustomer}"/>
6: </n:NavigateAction>
7: </i:EventTrigger>
8: </i:Interaction.Triggers>
9: </Button>
Above, we've attached an event-trigger (line 3) which executes a NavigationAction (line 4), and with it we pass a keyed parameter (line 5) which gets its value through binding - this wasn't possible earlier, though a small one it makes life that much easier. And by the way, if the xaml above looks scary, not to worry, the entire thing is perfectly Blendable.
For the sake of completion, I'll point out that you can receive the passed in parameters (like above) by implementing ISupportNavigationLifecycle interface in either the View or the ViewModel. As an example, below we're using the built-in NavigationViewModelBase class (which already implements ISupportNavigationLifetime), and we override its OnIntialize method to get hold of the passed-in parameters.
1: [MapViewModel(typeof(CustomerOverview))]
2: public class CustomerOverviewViewModel : NavigationViewModelBase
3: {
4: protected override void OnIntialize(ParametersCollection state)
5: {
6: this.Customer = (CustomerInfo)state["Customer"];
7: base.NotifyPropertyChanged(() => Customer);
8: }
9: public CustomerInfo Customer { get; private set; }
10: }
Except for the fact that it's not strongly-typed, this is a pretty convenient way of passing-in values - and in fact it also answers a common MVVM question about how do we pass-in values to the ViewModel. As I mentioned earlier passing parameters also works with controller-actions, so below is a simple example showing exactly that:
1: <Button Content="Analyse Customer">
2: <i:Interaction.Triggers>
3: <i:EventTrigger EventName="Click">
4: <n:ExecuteControllerAction Url="Tasks/Customers/Analyse">
5: <n:DependencyParameter Key="Customer" Value="{Binding ActiveCustomer}"/>
6: </n:ExecuteControllerAction>
7: </i:EventTrigger>
8: </i:Interaction.Triggers>
9: </Button>
Note the similarity between ExecuteControllerAction and NavigateAction, which is by design. And, on the receiving end, the Controller looks something like this:
1: [MapController("Tasks/Customers/{Action}")]
2: public class CustomerController : Controller
3: {
4: public void Analyse(CustomerInfo customer)
5: {
6: // business logic to analyse the customer
7: }
8: }
Above note how the "Customer" parameter is consumed in a strongly-typed manner, and the "{Action}" token is transposed to the method name (like in ASP.NET MVC). And I'll also just pin-point that the xaml above is entirely generated by Blend.
Default Xml-Namespace
Having to define separate xml-namespaces for each and every control, behavior, element etc has been a pain-point in Silverlight for only forever - but now with SL4's support for statically declare xml-namespace definitions, we've now got a simplified way to represent most of nRoute's functionality using just a single xml-namespace declaration.
As you can see above, the newly minted xml-namespace for nRoute is "http://nRoute/schemas/2010/xaml", along with its preferred prefix of "n". This works with both the full nRoute Framework and the Toolkit version, and against both Silverlight 4 and WPF but not with WP7. Also, for reasons unknown to me, tooling support in both Blend and Visual Studio seems to work better when using the predefined xml namespace - like above, we've got full intelligence support which was patchy before (note above we're using the awesome "Xaml Intellisense Presenter" plugin by Karl Shifflett).
Other Changes
Because now WPF supports the Visual State Manager (VSM), we've unified WPF and Silverlight's controls templates for all the Navigation Controls. Also, the default ErrorPage is now shared between the two frameworks. And since Silverlight now provides an Unloaded event, we've updated the BridgeViewModel behavior to allow calling a specified command when the View is being unloaded. We've also update support for Blend related tooling, specifically with behaviors and triggers in nRoute.
Updated Targets and Dependencies
The new release is versioned 0.4.5, while the one last week was 0.4.0; and summarized below for both the releases are their dependencies and target requirements:
| Target/Version |
nRoute Version 0.4.0 |
nRoute Version 0.4.5 (NEW) |
| Web |
Silverlight 3 |
Silverlight 4 |
| Desktop |
.NET Framework 3.5 sp1 |
.NET Framework 4.0 |
| Mobile |
WP7 (Silverlight 3) |
N/A |
| |
|
|
| Dependencies |
- Blend 3 SDK for System.Windows.Interactivity.dll
- Reactive Framework
for System.Observable.dll |
- Blend 4 SDK, available with Blend 4 RC
for System.Windows.Interactivity.dll
- Reactive Framework (only for Silverlight 4)
for System.Observable.dll |
The one notable above is the lack of support for WP7 in this release; it's because the WP7 tools haven't been updated for use with VS 2010 RTM - once they do, we'll update against it. However, you can use the earlier release, as there is no newly added functionality that targets Silverlight 3. Also as a cautionary note, if you are updating an existing nRoute application, be sure to update both System.Windows.Interactivity [version 4.0.x..] and Microsoft.Expression.Interactions [version 4.0.x..] else you'll get some rather cryptic and unhelpful errors.
Download the dlls this release from Codeplex
Read about what else is included this release, here.