Friday, 20 December 2013

Announcing Prism for the Windows Runtime for Windows 8.1

Back in May the patterns & practices team at Microsoft released a new guide for Windows 8 on creating Windows Store business apps using C# and XAML. The guide came with source code Prism for the Windows Runtime, source code for the AdventureWorks Shopper product catalog and shopping cart reference implementation, and documentation. The documentation provided guidance on how to implement MVVM with navigation and app lifecycle management, validation, manage application data, implement controls, accessible and localizable pages, touch, search, tiles, and tile notifications. It also provided guidance on testing an app and tuning its performance.

We’ve now updated the guide for Windows 8.1 and Visual Studio 2013 and it can be found on the Windows Developer Center.

What’s it all about?

Developers of Windows Store business apps face several challenges. App requirements can change over time. New business opportunities and challenges may present themselves. Ongoing customer feedback during development may significantly affect the requirements of the app. Therefore it's important to build an app that it is flexible and can be easily modified or extended over time.

Prism for the Windows Runtime provides an architecture that helps to do just that. It is designed to help developers create apps that need to accomplish the following:

  • Address the common Windows Store app development scenarios.
  • Separate the concerns of presentation, presentation logic, and model through support for Model-View-ViewModel (MVVM).
  • Use an architectural infrastructure to produce a consistent and high quality app.

The architecture provided by Prism helps to produce flexible, maintainable, and testable apps. It includes components that help to accelerate development of your app by providing support for MVVM, loosely coupled communication, and the core services required in Windows Store apps, allowing you to focus on developing the user experiences for your app. For more info see Prism for the Windows Runtime reference.

What do I get?

  • Documentation. The documentation provides guidance on how to implement MVVM with navigation and app lifecycle management, manage application data, implement controls, accessible and localizable pages, touch, validation, search, tiles, and tile notifications. It also provides guidance on testing your app and tuning its performance.
  • Portable Document Format (PDF). A PDF version of the on-line guidance, for printing or reading offline.
  • AdventureWorks Shopper reference implementation source code. A Visual Studio solution containing all the projects that make up the AdventureWorks Shopper product catalog and shopping cart reference implementation.
  • Quickstarts. The guidance includes a number of Quickstarts that illustrate specific concepts. Many of the Quickstarts use Prism for the Windows Runtime.
  • Prism for the Windows Runtime source code. Source code for the two libraries that help to accelerate the development of managed Windows Store apps.
  • Prism for the Windows Runtime NuGet packages. NuGet packages for the two libraries that help to accelerate the development of managed Windows Store apps.

Where should I start?


Where can I get help?

Prism for the Windows Runtime, like many patterns & practices deliverables, has a community site. On the community site you can post questions, provide feedback, connect with other users to share ideas, and find additional content such as extensions and training material. Community members can also help Microsoft plan and test future releases of Prism for the Windows Runtime. For more info see patterns & practices: Prism for the Windows Runtime.

What’s changed since the last release?

The release notes, which include what's new in this release and a change log, can be found on the community site. For more info see Prism for the Windows Runtime release notes.

Tuesday, 10 December 2013

Fourth drop of Prism for the Windows Runtime for Windows 8.1

The fourth drop of Prism for the Windows Runtime, and the associated AdventureWorks Shopper reference implementation, can be found on codeplex. To compile the code you’ll need Windows 8.1 and Visual Studio 2013. Obviously the usual caveats apply to the download, as it’s not final released code yet.

Change Log

  • Numerous bug fixes, including fixing UI issues related to high contrast.
  • Updates to the SearchUserControl.
  • Updates to the incremental loading quickstart.

Tuesday, 3 December 2013

DevWeek 2014

DevWeek is the UK’s leading conference for Software Developers, DBAs, and IT architects, and is held in London each year. In 2014 it’s being held at Central Hall, Westminster from 31st March to 4th April.

I’ll be delivering two sessions:

Building native Windows Store apps for C# developers

Accelerating Windows Store app development using Prism for the Windows Runtime

For the full conference agenda see here. Looking forward to seeing you there!

Improving code quality by using NDepend v5

Previously I’ve written about NDepend, a static analysis tool design to improve code quality by using code metrics and enforcing a series of rules. I was particularly impressed by the CQLinq feature, that allows you to write LINQ-style queries to check your code for certain rules. Since then NDepend 5 has been released, and I thought it’s time I checked it out.

The new features in this release include:

  • Support for Visual Studio 2013.
  • A new dashboard panel that shows the state of your code base at a glance.
  • Customisable trend metrics and charts.
  • Listing rules and queries according to a specific criteria, such as showing all the rules that have been violated.

Obviously, there’s a lot more new in NDepend 5 than I’ve listed here. For a full list see What’s new in NDepend v5.0.

I thought I’d put it through its paces by running it on a project I’m working on. Once NDepend has analysed your project it produces a HTML report that contains an overview of it’s findings.

image

The report then allows you to drill down into the findings. My starting point was to switch to the new dashboard view to examine the data.

dashboard[2]

Previously the overview of NDepend’s findings was pretty complicated. However, this isn’t the case with the new dashboard. While there’s a lot of information presented, it’s pretty easy to navigate through it. All the data that was available in previous releases of NDepend is still present. For more info see my previous blog post about NDepend.You can also turn off specific rules and queries that are producing violations that you find acceptable.

One of the great new features is its ability to display trend charts. It seems like it’d be a particularly useful feature for those on a team who are concerned with developer productivity.

Overall this latest release of NDepend has a much improved and responsive UI, and performs its analysis quickly. I’d imagine that a key scenario where NDepend would come into its own is tracking refactoring across a project, in order to gain a high level overview of the effect that the refactoring is having, while also being able to drill down into issues caused by specific refactoring's. In such scenarios NDepend would fit the bill perfectly.

Wednesday, 20 November 2013

Third drop of Prism for the Windows Runtime for Windows 8.1

The third drop of Prism for the Windows Runtime, and the associated AdventureWorks Shopper reference implementation, can be found on codeplex. To compile the code you’ll need Windows 8.1 and Visual Studio 2013. Obviously the usual caveats apply to the download, as it’s not final released code yet.

Change Log

  • Numerous bug fixes.
  • The Quickstarts have been retargeted to Windows 8.1 and any attached behaviours have been replaced with Blend behaviours.
  • Prism’s SearchPaneService and SearchQueryArguments classes have been deprecated.
  • Search activation support has been removed from the RI and the MvvmAppBase class.
  • Search is provided in the RI with the SearchBox control.
  • Search suggestions are provided from the web service on demand.
  • The HighlightSearchBehavior has been converted to an IAction named HighlightSearchAction.
  • Prism includes support for extended splash screens (see the ExtendedSplashScreenQuickstart sample).
  • AutoRotatingGridView controls are now retaining proportional scroll position across landscape/portrait orientation as well during the terminate/resume process.

Tuesday, 5 November 2013

Writing a custom Blend interaction to perform page navigation in Windows Store apps

Previously I wrote about replacing an attached behaviour that was used to execute a view model action, with a Blend behaviour that executes a view model command. The advantage of this approach is that you use what’s provided by the Blend SDK, rather than having to write your own attached behaviour, which may introduce errors, and associated unit tests.

I then updated the code as it was not necessary to pass a CommandParameter to the view model command. This is because the EventTriggerBehavior passes the associated EventArgs (in this case the ItemClickEventArgs) to the embedded action through the Execute method of the IAction. An action method signature takes the form shown in the following code example.

object IAction.Execute(object sender, object parameter)
{
    ...
}

Here, the sender will be the control to which the parent behaviour is attached (in my case a GridView), with the parameter receiving the ItemClickEventArgs from the EventTriggerBehavior. Because in my sample app a generic DelegateCommand is used for the view model command, the ItemClickEventArgs are passed from the action to the generic DelegateCommand. The problem then is that the view model has a dependency on the ItemClickEventArgs type, which is a UI specific concept. From a purist point of view for MVVM, this is unacceptable. In this blog post I’ll address this issue in order to remove the UI dependency from the view model.

Implementation

My previous post used the InvokeCommandAction interaction to execute a DelegateCommand in the MainPageViewModel class. In response the DelegateCommand executes a method which navigates to the PhotoPage. An alternative approach is to use the NavigateToPageAction interaction to perform the navigation directly. Not only does this remove the dependency on the ItemClickEventArgs type from the MainPageViewModel class, it also removes the DelegateCommand, the NavigateToPhoto method, and the need for the view model to have the NavigationService injected. The declaration of the interaction on MainPage then becomes as shown in the following code example.

<GridView Grid.Row="1"
          IsItemClickEnabled="True"
          ItemsSource="{Binding Photos}"
          Margin="140,0,0,0"
          SelectionMode="None">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemClick">
            <core:NavigateToPageAction TargetPage="PhotoViewer.Views.PhotoPage" />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    ...
</GridView>

An EventTriggerBehavior is used which handles the ItemClick event. The NavigateToPageAction specifies the page that will be navigated to through the TargetPage property. The overall effect is that when the ItemClick event fires on the GridView, the PhotoPage will be navigated to. In the PhotoPageViewModel class the OnNavigatedTo method can receive a navigation parameter from the NavigateToPageAction interaction, through the Parameter property.

The problem then becomes passing the clicked item from the GridView as the navigation parameter, as the GridView doesn’t have a property that represents the clicked item. The most suitable property is the SelectedItem property of the GridView. However, this is incorrect as the GridView doesn’t have selection turned on, and even if it did item selection occurs with the mouse by right clicking. Since there isn’t a SelectedItem, it can’t be bound to.

In addition, unlike the InvokeCommandAction interaction, the NavigateToPageAction interaction does not pass the EventArgs from the EventTriggerBehavior to its embedded action through the Execute method of the IAction. Therefore, it’s not currently possible to use the NavigateToPageAction interaction to perform navigation in this scenario and pass the required parameter type through to the OnNavigatedTo method of a view model class. Therefore, the solution then becomes to write a new interaction to do this.

Such an interaction has been developed as part of the Prism for the Windows Runtime project. The interaction is used by the AdventureWorks Shopper reference implementation, and is named NavigateWithEventArgsToPageAction. The latest drop of this project, which contains the interaction, can be downloaded here. To create a new action you must create a class that derives from the DependencyObject class, and implements the IAction interface. The IAction interface has only one method that needs to be implemented, named Execute.

public class NavigateWithEventArgsToPageAction : DependencyObject, IAction
{
    public string TargetPage { get; set; }
    public string EventArgsParameterPath { get; set; }
    object IAction.Execute(object sender, object parameter)
    {
        var propertyPathParts = EventArgsParameterPath.Split('.');
        object propertyValue = parameter;
        foreach (var propertyPathPart in propertyPathParts)
        {
            var propInfo = propertyValue.GetType().GetTypeInfo().GetDeclaredProperty(propertyPathPart);
            propertyValue = propInfo.GetValue(propertyValue);
        }
 
        var pageType = Type.GetType(TargetPage);
        var frame = GetFrame(sender as DependencyObject);
 
        return frame.Navigate(pageType, propertyValue);
    }
 
    private Frame GetFrame(DependencyObject dependencyObject)
    {
        var parent = VisualTreeHelper.GetParent(dependencyObject);
        var parentFrame = parent as Frame;
        if (parentFrame != null) return parentFrame;
        return GetFrame(parent);
    }
}

Here, the Execute method traverses the visual tree to obtain the Frame control used by the current page, and then calls its Navigate method to navigate to the target page, passing in the specified parameter. The overall effect of this interaction is to invoke navigation to a specified page, while allowing the event arguments to be passed as a parameter to the page being navigated to.

The NavigateWithEventArgsToPageAction interaction can then be invoked like any other Blend behaviour.

<GridView Grid.Row="1"
          IsItemClickEnabled="True"
          ItemsSource="{Binding Photos}"
          Margin="140,0,0,0"
          SelectionMode="None">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemClick">
            <behaviours:NavigateWithEventArgsToPageAction TargetPage="PhotoViewer.Views.PhotoPage"
                                                          EventArgsParameterPath="ClickedItem.Path" />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    ...
</GridView>

An EventTriggerBehavior is used which handles the ItemClick event. The custom NavigateWithEventArgsToPageAction interaction specifies the page that will be navigated to through the TargetPage property, with the navigation parameter being specified by the EventArgsParameterPath property. The overall effect is that when the ItemClick event fires on the GridView, the PhotoPage will be navigated to. In the PhotoPageViewModel class the OnNavigatedTo method will receive the value of the EventArgsParameterPath from the NavigateWithEventArgsToPageAction interaction.

The EventArgs associated with the ItemClick event on the GridView are of type ItemClickEventArgs. The ClickedItem property, specified in the EventArgsParameterPath property of the NavigateWithEventArgsToPageAction interaction, will be of the underlying type, which in this case is Photo (the Photo type is simply a wrapper around the FileInformation object). The Path property of the Photo object simply returns the Path property of the wrapped FileInformation object, which is a string containing the path of the associated file. It is this string that will be received by the OnNavigatedTo method in the PhotoPageViewModel class.

public async override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
{
    base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
    _filePath = navigationParameter as string;
   ...
}

Once the OnNavigatedTo method receives the path of the file, it can be loaded and displayed by the page. The advantage of using the custom NavigateWithEventArgsToPageAction interaction is that it removes any UI dependencies on EventArgs from view models.

Summary

In this blog post I’ve shown the custom NavigateWithEventArgsToPageAction interaction that can be used to invoke page navigation, while passing the EventArgs of the parent behaviour to the embedded action through the Execute method of the IAction. In a perfect world this solution would have been possible by using the NavigateToPageAction interaction. However, this is currently not the case. The advantage of the approach shown here is that it removes any EventArgs UI dependencies from view models.

The sample app can be downloaded here.

Friday, 1 November 2013

Second drop of Prism for the Windows Runtime for Windows 8.1

The second drop of Prism for the Windows Runtime, and the associated AdventureWorks Shopper reference implementation, can be found on codeplex. To compile the code you’ll need Windows 8.1 and Visual Studio 2013. Obviously the usual caveats apply to the download, as it’s not final released code yet.

Change Log

  • Applied the latest UX guidelines to all pages. In the Portrait view state content scrolls vertically.
  • Prism’s SettingsCharmActionItem class deprecated.
  • The GoBackCommand has moved into the VisualStateAwarePage class.
  • The custom AutoRotatingGridView control is used on the HubPage and CategoryPage.
  • Blend behaviors and actions have been used in the reference implementation:
    • The TopAppBarUserControl and the ShoppingCartTabUserControl use the EventTriggerBehavior and the NavigateToPageAction interaction.
    • The HubgPage, CategoryPage, GroupDetailPage, and the SearchResultsPage use the EventTriggerBehavior and the NavigateWithEventArgsToPageAction custom interaction. The NavigateWithEventArgsToPageAction custom interaction replaces the ListViewItemClickedToAction attached behavior, which is now deprecated.
    • The GroupDetailPage and the SearchResultsPage use the IncrementalUpdateBehaviour.

Wednesday, 30 October 2013

Using Blend behaviours in a Windows Store app – update 1

Previously I wrote about replacing an attached behaviour that was used to execute a view model action, with a Blend behavior that executes a view model command. The advantage of this approach is that you use what’s provided by the Blend SDK, rather than having to write your own attached behaviour, which may introduce errors, and associated unit tests.

Following a conversation with a colleague, I realised that while the app works, my use of the InvokeCommandAction was incorrect. This blog post will correct this.

Implementation

A Blend behaviour and a Blend action are used to execute a view model command when the ItemClick event fires on the GridView.

<GridView Grid.Row="1"
          IsItemClickEnabled="True"
          ItemsSource="{Binding Photos}"
          Margin="140,0,0,0"
          SelectionMode="None">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemClick">
            <core:InvokeCommandAction Command="{Binding PhotoNavigationCommand}" />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    ...
</GridView>

An EventTriggerBehavior is used which handles the ItemClick event. The InvokeCommandAction specifies the view model command that will be invoked when the event fires. Please note that it is not necessary to specify a CommandParameter to pass to the view model command. This is because the EventTriggerBehavior passes the associated EventArgs to the embedded action. The overall effect is that when the ItemClick event fires on the GridView, the PhotoNavigationCommand in the MainPageViewModel class is invoked, with the PhotoNavigationCommand receiving the ItemClickEventArgs of the GridView as a parameter.

public DelegateCommand<object> PhotoNavigationCommand { get; private set; }
 
public MainPageViewModel(IRepository repository, INavigationService navigationService)
{
    _repository = repository;
    _navigationService = navigationService;
    PhotoNavigationCommand = new DelegateCommand<object>(NavigateToPhoto);
}
 
private void NavigateToPhoto(object parameter)
{
    var photo = ((ItemClickEventArgs)parameter).ClickedItem as FileInformation;
    if (photo != null)
    {
        _navigationService.Navigate("Photo", photo.Path);
    }
}

In the MainPageViewModel class the PhotoNavigationCommand is a generic DelegateCommand of type object. This is an attempt to eliminate the dependency on ItemClickEventArgs in the view model. In the MainPageViewModel constructor the PhotoNavigationCommand is initialiased to a new DelegateCommand that will execute the NavigateToPhoto method. This method gets the photo that was clicked on and uses the NavigationService to navigate to the PhotoPage where the clicked on photo will be displayed. However, the problem remains that the MainPageViewModel class still has one final dependency on ItemClickEventArgs, which is a UI specific concept. From a purist point of view for MVVM, this is unacceptable.

Summary

In this blog post I’ve updated my use of InvokeCommandAction to execute a view model command. There’s still a problem in that the MainPageViewModel class has a dependency on the ItemClickEventArgs type, which is a UI specific concept. From a purist point of view for MVVM, this is unacceptable. I’ll address this issue in a future blog post.

The sample app can be downloaded here.

Monday, 21 October 2013

First drop of Prism for the Windows Runtime for Windows 8.1

The first drop of Prism for the Windows Runtime, and the associated AdventureWorks Shopper reference implementation, can be found on codeplex. To compile the code you’ll need Windows 8.1 and Visual Studio 2013. Obviously the usual caveats apply to the download, as it’s not final released code yet.

Change Log

Wednesday, 16 October 2013

Using Blend behaviours in a Windows Store App

Previously I’ve demonstrated a sample PhotoViewer app that displays photo thumbnails on the MainPage, and that displays a selected photo on the PhotoPage. The app can also convert a colour photo to greyscale on the PhotoPage. In addition, the app serializes frame and page state during suspension, and deserializes it when the app reactivates following termination.

The app uses an attached behaviour on the GridView on the MainPage to execute a view model action in response to the ItemClick event firing on the GridView. This approach eliminates the need for an event handler in the code-behind of the MainPage class, and ensures that navigation is invoked from the view model class, where it can be easily tested.

With the release of Visual Studio 2013 Blend behaviours are now supported in Windows Store apps. A Blend behaviour adds some behaviour to an element in your app, and has a method that’s invoked when the behaviour is attached to a DependencyObject, and a method that’s invoked when it’s detached. An action contains only one method that is invoked when a certain condition is met, such an event being raised. The Behaviours SDK consists of the following actions and behaviours:

CallMethodAction: An action that calls a method on a specified object when invoked.

ChangePropertyAction: An action that will change a specified property to a specified value when invoked.

GoToStateAction: An action that will transition a FrameworkElement to a specified VisualState when executed.

InvokeCommandAction: Executes a specified ICommand when invoked.

NavigateToPageAction: An action that switches the current visual to the specified Page.

ControlStoryboardAction: An action that will change the state of the specified Storyboard when executed.

PlaySoundAction: An action that will play a sound to completion.

DataTriggerBehaviour: A behaviour that performs actions when the bound data meets a specified condition.

EventTriggerBehaviour: A behaviour that listens for a specified event on its source and executes its actions when that event is fired.

IncrementalUpdateBehaviour: A behaviour that allows incremental updating of ListView and GridView contents to support faster updating. By attaching this behaviour to elements in the ItemTemplate used by these views, some of the updates can be deferred until there is render time available, resulting in a smoother experience.

You can create your own action by adding a class to your project that derives from DependencyObject and implements the IAction interface. Similary you can create a behaviour by adding a class to your project that derives from DependencyObject and implements the IBehavior interface.

In this blog post I’ve replaced the attached behaviour that was previously used with a Blend behaviour that has the same effect.

Implementation

The first step is to add a reference to the Behaviours SDK to your project.

image

Then the Microsoft.Xaml.Interactivity and Microsoft.Xaml.Interactions.Core namespaces should be imported into the XAML of the page you want to use a Blend behaviour from.

<prism:VisualStateAwarePage
    ...
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    ...>

Previously in the app, the GridView used an attached behaviour to execute a view model action when the ItemClick event fires on the GridView. Here, a Blend behaviour and a Blend action is used to achieve the same effect.

<GridView Grid.Row="1"
          IsItemClickEnabled="True"
          ItemsSource="{Binding Photos}"
          Margin="140,0,0,0"
          SelectionMode="None">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemClick">
            <core:InvokeCommandAction Command="{Binding PhotoNavigationCommand}"
                                      CommandParameter="{Binding Path=SelectedItem}"/>
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
    ...
</Grid>

An EventTriggerBehavior is used which handles the ItemClick event. The InvokeCommandAction specifies the view model command that will be invoked when the event fires, and passes a parameter to the view model command. The overall effect is that when the ItemClick event fires on the GridView, the PhotoNavigationCommand in the MainPageViewModel class is invoked, with the PhotoNavigationCommand receiving the SelectedItem property of the GridView as a parameter.

public DelegateCommand<ItemClickEventArgs> PhotoNavigationCommand { get; private set; }
 
public MainPageViewModel(IRepository repository, INavigationService navigationService)
{
    _repository = repository;
    _navigationService = navigationService;
    PhotoNavigationCommand = new DelegateCommand<ItemClickEventArgs>(NavigateToPhoto);
}
 
private void NavigateToPhoto(ItemClickEventArgs parameter)
{
    var photo = parameter.ClickedItem as FileInformation;
    if (photo != null)
    {
        _navigationService.Navigate("Photo", photo.Path);
    }
}

In the MainPageViewModel class the PhotoNavigationCommand is a generic DelegateCommand of type ItemClickEventArgs. This is necessary so that the command receives the event data for the ItemClick event. In the MainPageViewModel constructor the PhotoNavigationCommand is initialiased to a new DelegateCommand that will execute the NavigateToPhoto method. This method gets the photo that was clicked on and uses the NavigationService to navigate to the PhotoPage where the clicked on photo will be displayed.

Summary

In this blog post I’ve replaced the attached behaviour that was previously used to execute a view model action with a Blend behaviour that executes a view model command. The advantage of this approach is that you use what’s provided by the Blend SDK, rather than having to write your own attached behaviour, which may introduce errors, and associated unit tests.

The sample app can be downloaded here.