Sunday, November 04, 2012

Okra App Framework v0.9.5 Released

The latest update to the Okra App Framework has just been released and is available from the Okra CodePlex site and via NuGet.

New Features in This Release

  • Settings support
    • The framework now includes support for the Windows 8 settings charm. Custom application settings panes can be defined using the MVVM pattern and Okra will handle the wiring required to show the settings pane – I will write about this in detail in an upcoming blog post.
    • A SettingsChrome control is included to allow developers to easily match the settings UI of the default Windows 8 applications
  • The NavigationManager class has now been refactored to derive from a NavigationBase class with the base functionality. This allows the creation of custom navigation managers (for example the SettingsPaneManager)
  • Updated to support MEF v1.0.16
  • Minor improvements and bug fixes

Monday, October 29, 2012

App Search and the Okra App Framework

One advantage of the Okra App Framework over other MVVM-based application frameworks is that it is designed from the ground up to work great with Windows 8. Over the next few versions this will become more evident as features are added to support the various Windows 8 system contracts – search, settings, sharing, etc.

In this post I will describe how the Okra App Framework makes it easy to add search to your application using the same MVVM principles that you are using for the rest of your application.

The Search Contract in Windows 8

When developing Windows Store applications many developers will want to take advantage of the Windows 8 search charm. This allows users to search across all applications from a single, consistent entry point. In order to add search functionality you would generally override the OnSearchActivated(…) method in the App.xaml.cs code-behind. In fact the standard Visual Studio search page template will add the code required to do this. For a great Windows Store application however you would want to,

  • Fully follow the Windows search design guidelines (available here)
  • Preserve the existing application state and correctly handle back navigation from the search page
  • Navigate to a suitable page (normally the application home page) if an empty search is performed
  • Improve performance by attaching to the SearchPane.QuerySubmitted event where possible
  • You may also want to implement the search page using the MVVM pattern

By simply using the Okra App Framework search manager it will take care of these requirements.

Adding Search to Your Application with the Okra App Framework

The Okra App Framework provides a search manager to handle the process of activating search in your application. This is represented by the ISearchManager interface,

public interface ISearchManager
{
    string SearchPageName { get; set; }
}

By default the SearchPageName property is set to null, and Okra will not handle search activation. To opt-in to the search integration you should set the page name for search in your application’s bootstrapper SetupServices() method.

public class AppBootstrapper : OkraBootstrapper
{
    protected override void SetupServices()
    {
        SearchManager.SearchPageName = "Search";
    }
}

By adding this single line your application has been enabled for search, and a page named “Search” will be navigated to when the user performs a search within your application (note that you will also need to declare that your application supports search in the application manifest).

Defining Your Search Page


Because search uses the standard Okra page discovery mechanisms you define your search page and view-model as you would any other page within your application,

[PageExport("Search")]
public sealed partial class SearchPage : LayoutAwarePage
{
    ...
}
 
[ViewModelExport("Search")]
public class SearchViewModel : NotifyPropertyChangedBase, ISearchPage
{
    ...
}

One thing to note is that the search view model implements the ISearchPage interface (this could also be implemented by the page if you are not using the MVVM pattern),

public interface ISearchPage
{
    void PerformQuery(string queryText, string language);
}


This method will be called whenever the page should show a new set of search results. In this method you provide the application logic to perform the search operation and display the results to the user. Note that this may be called multiple times for a single page as the user performs subsequent searches and you should refresh the content with the new results.

Summary


In the above discussion I have shown how the Okra App Framework makes it simple to implement search functionality in applications based on the MVVM pattern.

A sample search application is available from the Okra CodePlex downloads section. This is based on the Visual Studio search template, but modified to correctly implement the MVVM pattern.

Wednesday, September 05, 2012

Convention Based Page Discovery With The Okra App Framework

One of the key features of the Okra App Framework for developing Windows 8 apps is the navigation framework with its support for the MVVM pattern. By default pages and view-models are marked with attributes so that the framework can locate them. In this post I will describe how you can enable an alternative convention based approach.

The Default Attribute Based Approach

When using the Okra App Framework navigation support all pages are represented by a page name. So that the framework can locate the associated pages and view-models these are normally attributed with either the PageExportAttribute or ViewModelExportAttribute respectively (for more information see my previous post). For example for a page named “Foo” the classes would be attributed as,

[PageExport("Foo")]
public sealed partial class FooPage : LayoutAwarePage
{
    ...
}
 
[ViewModelExport("Foo")]
public class FooViewModel
{
    ...
}

A Convention Based Approach

Often however there will be a common naming pattern throughout the application. In the example above all pages are named XxxPage and view-models named XxxViewModel, where “Xxx” is the associated page name. In a convention based approach you no longer need to apply attributes to classes. Instead they are automatically discovered based on a common naming system.

Since the standard Okra bootstrapper uses MEF for composition (for example when using the Okra.MEF NuGet package), we can use the MEF convention based discovery. To enable this we need to add the following code to the application bootstrapper,

public class AppBootstrapper : OkraBootstrapper
{
    ...
 
    // *** Overriden base methods ***
 
    protected override ContainerConfiguration GetContainerConfiguration()
    {
        ConventionBuilder conventionBuilder = new ConventionBuilder();
 
        conventionBuilder.ForTypesMatching(type => type.FullName.EndsWith("Page"))
                         .Export(builder => builder.AsContractType<object>()
                                                   .AsContractName("OkraPage")
                                                   .AddMetadata("PageName", type => type.Name.Substring(0, type.Name.Length - 4)));
 
        conventionBuilder.ForTypesMatching(type => type.FullName.EndsWith("ViewModel"))
                         .Export(builder => builder.AsContractType<object>()
                                                   .AsContractName("OkraViewModel")
                                                   .AddMetadata("PageName", type => type.Name.Substring(0, type.Name.Length - 9)));
 
        return GetOkraContainerConfiguration()
                .WithAssembly(typeof(AppBootstrapper).GetTypeInfo().Assembly, conventionBuilder);
    }
}

With this code in place we can greatly simplify our page and view-model definitions to the following. Note that since we follow the convention we no longer need to add any attributes.

public sealed partial class FooPage : LayoutAwarePage
{
    ...
}
 
public class FooViewModel
{
    ...
}

Summary

As I have shown, when using the Okra App Framework navigation support you can simplify app development by using a convention based approach to defining pages and view-models for the MVVM pattern.

A sample application demonstrating this is available from the Okra CodePlex downloads.

Monday, August 27, 2012

Okra App Framework v0.9.4 Released

Version 0.9.4 of the Okra App Framework is now available via CodePlex and NuGet. Since the core functionality of the framework has been in testing for some time now I have removed the ‘beta’ suffix from the version number, with the benefit that the framework should show in the default NuGet feed.

Minimal changes and bug fixes were made in this release, with the key change being updating the Okra App Framework to work against the RTM version of MEF (v1.0.15).

Sunday, August 12, 2012

Cocoon is now the Okra App Framework

Today I would like to announce that the Cocoon framework is now know as the ‘Okra App Framework’. It still includes the great features previously available in the Cocoon framework, but from now onwards will be developed under the new name.

How to Get The Okra App Framework

The ‘Okra App Framework’ CodePlex site is available at http://okra.codeplex.com/ (all previous code/downloads/discussions have been migrated from the old site, and any links to the previous URLs will redirect to their new location).

In addition there are two new NuGet packages,

If you are using the Cocoon NuGet packages and wish to get future releases then you should use the NuGet package manager to uninstall Cocoon and then install the new Okra App Framework package.

Okra App Framework Release 0.9.3-beta

Along with the name change a new version of the framework has been released via NuGet and the Okra App Framework CodePlex downloads page. The changes include,

  • Namespace changes from ‘Cocoon’ to ‘Okra’ and from ‘CocoonBootstrapper’ to ‘OkraBootstrapper’ (a simple find-and-replace in your project should solve any errors occurring from this).
  • Addition of a SearchManager that allows an easy, view-model centric, implementation of the Windows 8 Search contract (I will aim to detail this in a future blog post).
  • The ActivationManager class allows extensible handling of application activation (you can write activation handlers to handle any of the activation types).
  • Upgraded to MEF version 1.0.13-rc.
  • Removal of the previous obsoleted VirtualizingVector with the recommendation that VirtualizingVectorBase is used going forward (although if you still require VirtualizingVector it can be downloaded as part of any of the previous source releases and copied into your own projects).

Why the Name Change?

I recently received a message from a member of the Apache Software Foundation, informing me that they also have a web application framework named Apache Cocoon. To avoid any confusion that may arise between the two frameworks the best approach going forward was a name change.

Monday, August 06, 2012

Shell Based Navigation in Cocoon

I recently had a query in the Cocoon CodePlex forums regarding how to support an application shell when using the Cocoon framework’s navigation support. By default the Cocoon navigation framework will display pages full screen, with each navigation replacing the previous page with the next. There are some occasions however where it makes sense to have an application shell that takes up the full screen, with the page navigation occurring in a region within this.

A typical example would consist of a fixed region dedicated to navigation at the top of the screen, with the page content filling below. The end result looks like,

image

Creating an Application Shell in Cocoon

The key to creating an application shell in Cocoon is the INavigationTarget interface. This has only a single method named NavigateTo(…). When implemented by an application, any calls to the navigation framework will result in a call to this method with the page to display. The framework itself will handle the creation and wiring up of views and view-models, the navigation stack, persistence and other aspects of navigation.
In our example application we will use the MVVM pattern to define our application shell, hence we have a ShellViewModel,

   1: [Export(typeof(INavigationTarget))]
   2: [Shared]
   3: public class ShellViewModel : NotifyPropertyChangedBase, INavigationTarget
   4: {
   5:     // *** Fields ***
   6:  
   7:     private object content;
   8:     private ShellPage shellPage;
   9:  
  10:     // *** Properties ***
  11:  
  12:     public object Content
  13:     {
  14:         get
  15:         {
  16:             return content;
  17:         }
  18:         set
  19:         {
  20:             if (content != value)
  21:             {
  22:                 content = value;
  23:                 OnPropertyChanged();
  24:             }
  25:         }
  26:     }
  27:  
  28:     // *** INavigationTarget Methods ***
  29:  
  30:     public void NavigateTo(object page)
  31:     {
  32:         // If this is the first navigation then create the shell view and bind to this view model
  33:  
  34:         if (shellPage == null)
  35:         {
  36:             shellPage = new ShellPage();
  37:             shellPage.DataContext = this;
  38:         }
  39:  
  40:         // Set the content for the shell to the specified page
  41:  
  42:         this.Content = page;
  43:  
  44:         // Set the shell view as the window content
  45:  
  46:         Window.Current.Content = shellPage;
  47:     }
  48: }

The ShellViewModel exposes a single property named ‘Content’ that will contain the page to display and will be bound to in the view. In our NavigateTo(…) method we firstly determine if we have created the associated view and create this is necessary. We then set the ‘Content’ property to the supplied page and this ensure that the view is displayed in the window. Finally we mark the class as a shared export of INavigationTarget using the MEF attributes. Note that since we will never be navigating explicitly to the shell then we do not need to decorate this with a ViewModelExport attribute.

In the sample code the shell view model also exposes a ‘GoBackCommand’ that allows you to include a back navigation button within the shell region.

The ShellPage.xaml file contains the view for the application shell. This simply contains the required elements for the upper portion of the screen, with a ContentControl bound to the view models ‘Content’ property. It is within this ContentControl that the pages will be displayed. The key elements are shown below,


   1: <Grid Style="{StaticResource LayoutRootStyle}">
   2:     ...
   3:  
   4:     <!-- Back button and page title -->
   5:     <Grid>
   6:         <Grid.ColumnDefinitions>
   7:             <ColumnDefinition Width="Auto"/>
   8:             <ColumnDefinition Width="*"/>
   9:         </Grid.ColumnDefinitions>
  10:         <Button x:Name="backButton" .../>
  11:         <TextBlock x:Name="pageTitle" .../>
  12:     </Grid>
  13:     <ContentControl Content="{Binding Content}" .../>
  14: </Grid>

When the application is run the NavigationManager will automatically locate the INavigationTarget through the MEF export and direct all navigation through this.

Summary

I have shown above how you can implement an application shell using the Cocoon framework. The sample application with full source code is available from the Cocoon CodePlex downloads.

Tuesday, July 24, 2012

Cocoon Framework v0.9.2 Released

As I discussed in my previous post on NuGet support in the Cocoon framework, I will be distributing major updates within the framework as new releases. Today I am pleased to say that version 0.9.2 is available from both the Cocoon CodePlex site and downloadable directly from NuGet.

New Features in This Release

This release has mainly focussed upon updates to the Cocoon data framework. In particular,

  • Significant improvements in how the data framework handles caching of list items.
  • Infrastructure added to support change notifications for data lists.
  • The ‘PagedDataListSource’ class now includes a ‘PageCacheSize’ property that allows you to specify the maximum number of pages to hold in memory at any one time (by default all pages are stored).
  • Introduction of an ‘IncrementalLoadingDataList’ class. This supports the Windows 8 Metro ISupportIncrementalLoading interface. This allows a data bound UI to download a small subset of a large list of items, with further items being retrieved and added when the user scrolls to the end of the list.
  • A Refresh() method has been added to SimpleDataListSource and PagedDataListSource. This allows you to clear the internal cache and re-fetch any data that may have changed. Any attached data lists will automatically update to reflect the changes.

Some improvements to the navigation framework include,

  • Updated to support MEF version 1.0.11-rc.
  • Changes to the ‘CocoonBootstrapper’ to help with a convention based approach to exporting pages and view models (I will write a blog post on this in the future).
  • The navigation manager now exposes a ‘CurrentPage’ property so that you can programmatically determine the currently displayed page and associated information.
  • Pages and view-models can now be named by specifying a type as an alternative to a string page name.
  • A MEF sharing boundary (named “page”) has been placed around each page and view model pair (see here for more information on MEF sharing boundaries).
  • Some common MVVM base classes have been included. Whilst you are not restricted to using these to take advantage of the Cocoon framework they provide basic functionality that is common to many applications. These classes include,
    • DelegateCommand and DelegateCommand<T> – implementations of the ICommand interface that allow you to bind UI interactions to methods on your view models.
    • NotifyPropertyChangedBase – provides a simple base class for view models that supports property change notification.
  • A number of other bug fixes.

Breaking Changes

Unfortunately there are a small number of breaking changes in this release. For most developers however the changes should be minimal.

  • ‘SpecialPageNames.HomePage’ has been renamed ‘SpecialPageNames.Home’.
  • The contract for IDataListSource has changed. Note that this should only affect developers who are writing custom IDataListSource implementations. If you are using SimpleDataListSource or PagedDataListSource then existing code should not be affected. In particular the changes are,
    • Addition of an IndexOf(…) method to the IDataListSource interface.
    • The data list source implementations are now fully responsible for caching of data.
  • The ‘InternalList’ property of ‘DataListSourceBase’ has been removed (derived classes should create their own internal cache) and the corresponding property in ‘SimpleDataListSource’ and ‘PagedDataListSource’ has been made private.
  • VirtualizingVector<T> is now marked as Obsolete – it is recommended that you use the data list support or the new VirtualizingVectorBase<T>.

Getting the Latest Version of Cocoon

To get the latest release of the Cocoon framework the best place to start is using the NuGet package manager to download the “Cocoon Framework” package (see here for more information). If you are already using Cocoon via NuGet then you should be able to update your solution to the latest version directly through the NuGet package manager.

Alternatively the source code is available via the Cocoon CodePlex downloads page. As always the latest interim code drops are also available from CodePlex under the source code tab.