Code for Boise Code Camp 3-16-2013

March 15, 2013

Data Caching Session

This example application is for the session, “An Approach to Real World Application Data Caching” can be downloaded below. Included in the download is the demo application, the Ocean 3 framework binaries, and the  PowerPoint deck.

This application demonstrates one solution to real world data caching.  I use the techniques presented here in production applications with many users.

In the future, I’ll write a full blog post on this and possibly post a video walkthrough. I’ll also post the Ocean 3 code, just have not had time to document and write a full example application.

Mole Session

A pdf of the Mole slides can be downloaded below.

Mole can be purchased or a demo of Mole can be downloaded at


After downloading change the extension from .zip.DOC to .zip. This is a requirement of WordPress. You will also need to Unblock the file using the file properties dialog in Windows Explorer.

Download (Data Caching Demo w/Database (1.4 MB))

There is a database backup in the \DataCachingDemo\Database Backup folder.  You’ll need to restore this to a SQL Server 2008 R2 or SQL Server 2008 R2 Express. If you restore to SQL Server, you’ll need to change the connection string to point to your server.  Currently, the demo application points to SQL Server Express.

Download (Mole Session Slides in PDF (613 KB))

Have a great day,

Just a grain of sand on the worlds beaches.

Speaking at Boise Code Camp March 16, 2013

February 25, 2013

I’m very much looking forward to the 16 March, 2013 Boise Code Camp. Speakers have signed up for some very cool and informative talks.

I’ve signed up for two sessions myself. The abstracts can be viewed here.

  • An Approach to Real World Application Data Caching
  • Using Mole for Debugging Visual Studio 2010 and 2012 Applications

In addition, I’ll release Ocean 3 as part of the associated session source code.

Have a great day,

Just a grain of sand on the worlds beaches.

Boise Code Camp Prism, Ocean 3 Session

March 24, 2012

The links to the code presented at the Boise Code Camp is in the below Downloads section.

This links include Ocean 3 and a modified Prism 4 library that has two new features.

The Ocean 3 solution includes a Prism Ocean Demo application that shows off Ocean working with Prism. In a later release, I’ll add database demonstration code as well that uses the new and improved Service<T> and Repository<T>.

The demo application shows off:

  • WPF Ribbon being populated by a Prism Region; when forms are navigated to, their respective ribbon tabs are automatically rendered.
  • Automatic view/view model wiring up by the Unity container. No view or view model navigation registrations required.
  • Automatic setting of the correct IRegionManager on all view models; this region adapter does not draw the IRegionManager out of the IoC container, instead it uses the one assigned to the view. This technique prevents the incorrect IRegionManager being assigned in cases of child windows or scoped regions.
  • Demonstration of a child window hosting a form; that same form can be shown within the shell or child window requiring no form or view model modifications to function correctly; i.e. no “if in popup then do this code.”
  • When views are navigated away from, the currently focused control is cached; when that same instance of that form is navigated back to, focus will automatically be set to the correct control.
  • Queued dialog service for forms.
  • The view modal dialogs are asynchronous, by not blocking the UI thread, a form that has a dialog displayed, can be navigated away from and navigated back to.
  • When a view has a view modal dialog displayed, the views ribbon tabs are automatically disabled.
  • Ocean FormControl that provides many services for LOB forms.
  • Ocean FormNotificationControl that shows the form status from a validation perspective.
  • Ocean provides a comprehensive validation stack.
  • In addition, many small features are also shown.

I’ll release a new version of BBQShack soon, PrismBBQShack. This is a complete end-to-end store application that will show off all features of Ocean 3 (like the data stack) and will have a Win8, WinRT XAML touch-enabled point of sale application.


After downloading, you MUST read the READ ME NOW.txt file in the Acme.Example solution.

After downloading, you must rename the to downloads from .zip.doc to .zip.  This is a requirement of Word Press.

Ocean 3

Modified Prism 4

To use the modified Prism 4 download, after unzipping, go to the \Prism\Prism4\ folder and run these two batch files:

  • Run Update Prism Binaries.bat
  • RegisterPrismBinaries.bat

They will rebuild the supplied modified Prism 4 and will register this version of Prism in the registry so that you can use the Add References dialog. This modified version of Prism will work with any current Prism application as no API’s were removed or changed, only added.

Have a great day,

Just a grain of sand on the worlds beaches.

Boise Prism, Unity, WPF, MVVM Code and Decks

June 29, 2011

Everyone had a great time in Boise this week with developers from the United Kingdom and all over the United States.  WPF is alive and well and being used in corporate development along with Prism!


C# early version of Ocean.

  • Data Binding
  • M-V-VM
  • Commands in M-V-VM
  • Dialogs in M-V-VM
  • Data Validation
  • M-V-VM Tips & Tricks
  • Unit Testing & Moq
  • Introduction to Prism
  • Unity and Dependency Injection
  • Shell and Bootstrapping
  • Modules
  • Regions
  • Events
  • Navigation


The download includes PowerPoint decks for most of the sessions and source for all sessions.  Also included is an  Extras folder with goodies.


You can download the code and decks from my Sky Drive here.

Have a great day,

Just a grain of sand on the worlds beaches.

Karl’ Roadmap Nov – Dec 2010

October 31, 2010

While my blog has been a little on the quiet side, I’ve been going like a rabbit with his tail on fire.  Metaphorically speaking, “What lies beneath the water line of the iceberg is about to be unveiled.”

I’ve been getting emails, Tweets, and blog comments asking me about XAML Power Toys, Ocean, Mole 2010, my upcoming cruise, Prism, In the Box, patterns & practices 2010 Symposium code; so I thought a short roadmap post is in order.

Prism 4

Prism 4 will RTW either this Thursday, 4 November 2010 or early the following week.

The patterns & practices Prism team has invested a lot of resources in the Prism Library and written guidance.  The documentation has been completely rewritten with new topics added such as MVVM, MEF and navigation.

Once released, I’ll blog regularly on the features and content of the Prism guidance.  Additionally, I’m researching the possibility of conducting three Prism events; I’m thinking of using the two day event model, holding the sessions over a Friday and Saturday.  Once the dates and locations are firmed up, I’ll provide plenty of lead time to plan and register.

patterns & practices 2010 Symposium Code

On the day Prism v4 ships, I’ll post the MVVM Training that was package using In the Box.  In the Box is explained below.

This Friday, 5 November 2010 I’ll publish a blog post and video covering the Prism Region Navigation sample application that also demonstrated the Task Parallel Library Futures pattern that streamlines view model code.

XAML Power Toys

I was hoping to get to the next release in November but am putting this work off until early December.  I’ll release a new version with the suggestions and performance fix on 19 December 2010.  If you have a suggestion or requested fix, please leave a comment here.

Mole 2010

Team Mole has put in several hundred hours in this new release.  We have been cautious with our release, wanting to provide the very best product.  Mole 2010 is code complete, has a great new UI and many new features you’ll love.  Team Mole is completing the documentation and videos and hopes to ship very soon.

You can follow Josh Smith’s blog and my blog for the release announcement.

We can also be followed on Twitter:


I’ve already ported Ocean to C#, Windows Phone 7 and released it here.

I’m currently porting Ocean for WPF and Silverlight to C#.

While on my cruise over Thanksgiving, I’ll write a reference implementation that shows Ocean v3 in action.

Expect this to be released on Sunday, 5 December 2010.

Mexican Riviera Cruise

It has been a year and the time has come to set sail again; this time to the Mexican Riviera.  With three full days at sea and each night spent at sea, kdawg will have plenty of coding time!  No email, no phone, no Internet, just heads down coding.  The sounds and scent of the ocean breeze; gentle rolls of the ship and room service grill cheese, sets the stage for a week of creativity and productivity.

I’ve been wanting to update my Stuff application to consume data and to support many more item types.

The core scenario is to be able to look up movies, books, games, music and software I currently own using a phone.  This would allow me to see what I own, if I don’t have it, quickly check the price at and either purchase it at the store (automatically adding to my database) or put the item in my shopping cart.

To accomplish this, I’ll be taking these three patterns & practices assets out for a test drive, Prism, Windows Phone 7 Developer Guidance, and Unity Application Block.  To those, I’ll add Ocean v3 to the supporting cast.

The application will have an oData cloud services component with WPF, Silverlight, Windows Phone 7 and ASP.NET MVC3 front ends.  The cloud services component will be hosted on my Discount ASP.NET site.  Each developer wanting to have their own live service, will need to deploy the backend to their own hosted web server.

Developers will be able to compile and run the application locally on their system.  For access you’ll need a free developer account.  Again, to use the application remotely, you’ll need to host the cloud component on your web server.

What is exciting to me is the notion of a single cloud service consumed by the very cool UI stacks offered by Microsoft .NET.

It will a lot of fun working with the technologies that are new to me, Windows Phone 7 and ASP.NET MVC3.  When coding, I’ll be looking for code-reuse opportunities when writing the WPF and Silverlight applications powered by the above patterns & practices assets.  All-in-all, a very relaxing and fun vacation.

Just so you don’t think I’m insane and never stray from my keyboard, I’ve signed up for a 7 hour dolphin training experience and a day on the jet ski during my cruise.

The 7 hours with Flipper is one of those bucket list goals I can finally check off and is the main reason for visiting the Mexican Riviera.  The day on the jet ski will be one big nasty adrenalin rush.  The other day in port will be spent shopping for some cool shirts, a sombrero and tasting the local cuisine.

Expect this application to be released on Sunday, 5 December 2010.

In the Box


At the patterns  & practices 2010 Symposium and at the post PDC 2010 Windows Phone 7 Lab Day, I previewed, “In the Box” and the first training package, MVVM Training.

So far response to this format and the content has been very favorable.

The training is unique because it’s consumed within Visual Studio 2010.  The interface is pictured below.

To create the content, I followed the training videos presented on Channel9 here.  For more information you can also follow Michael Lehman’s blog.

This will ship from the Visual Studio Code Gallery on the same day Prism v4 ships, either Thursday, 4 Nov or the following week.  My next planned training package for In the Box will be Prism v4.  Remember, every thing comes “In the Box.”


Click the image to view full size

Date Summary

Check my blog or follow me on Twitter for these announcements:

  • 4 Nov – Prism v4 (could possibly ship the following week)
  • 4 Nov – In the Box (could possibly ship the following week)
  • 5 Nov – Prism Region Navigation with Task Parallel Library Futures example  (could possibly ship the following week)
  • 5 Dec – Ocean v3, and the vastly upgrade Stuff application with multiple UI front ends
  • 19 Dec – XAML Power Toys update


WOW – what a way to close down 2010!  Looking to power down after the 19th of December; then crank back up January 2011.

Have a great day,

Just a grain of sand on the worlds beaches.

Windows Phone 7 – Application Lifecycle – Ocean for the Phone

October 17, 2010


On October 9th 2010 I did a presentation at the Silicon Valley Code Camp on the Application Lifecycle for Windows Phone 7.  This last week was KA-ray-zeee busy at work and I didn’t want to just post the slides and code I had at code camp.  Better to wait and really do a good job, so here it is.


First, I would like to acknowledge the outstanding decks and examples that the Microsoft Windows Phone 7 Evangelism Team has been and continues to publish.  Team members I’ve been working with are Yochay Kiriaty and Jaime Rodriguez.

I created the provided deck from several decks published by the Evangelism Team.  I edited and added content for the session I did.

For the three example applications, I studied the Evangelism Team’s material, samples on the web, added many hours of learning and ported Ocean to the Windows Phone 7.

This was a lot of fun, in-fact more pure fun than I’ve had in a while.  Don’t get my wrong, I love what I do everyday and the opportunities I’ve been blessed with at Microsoft.  Maybe because the phone is new, I didn’t really know much about it, but was able to understand it and get productive quickly.  Additionally, the Visual Studio 2010 tooling worked great. 

No other way to say it, “developing on Windows Phone 7 is a lot of fun.”  Very much looking forward to getting my own device.

I’m encouraged that Microsoft has a commitment to the XAML language and that I was able to leverage my huge investment in WPF with Silverlight 3-4, and now the Windows Phone 7.  The ability to transfer my investment across platforms and devices is a fantastic benefit to developers on Microsoft’s stacks.

Let me now turn our attention to what is in the box (the download).

Presentation Slide Deck

The deck is in the solution folder and explains each topic clearly.  The application lifecycle concepts are repeated several times in different ways so the reader can grasp tombstonning.

The code snippets in the deck come from TravelReporting project and the OceanFramework.Phone project.

ApplicationLifeCycle Project

The purpose of this application is to provide a nice clear log of the application’s constructors, methods and events as they execute.  It is critical to your success that you learn the phone’s application lifecycle.  This program can help with that.

Crack the App.xaml open and look at the CustomHyperlinkButtonStyle.  I use this to make a Hyperlink control look and act like a Button.  I do this so that I can navigate from XAML and not have to wire up a command or click event handler.  You’ll see this style used in all three applications where appropriate.

Notice how clean my debug output window is.  That’s because I’ve turned off the other messages.  To turn off the other messages, right click the debug output window while debugging.  Then unselect messages on the context menu that you do not want to see.  Below, I just want to see my phone messages, so I’ve left Program Output selected.



Creating the log messages is very simple, just call Logger.Log();  You can also pass an optional notes string.

void Application_Launching(Object sender, LaunchingEventArgs e) {

The magic is in the below Log method.  By creating a StackTrace object, I can extract the calling type and method from the appropriate stack frame.  This type of logging is much better than having to craft each individual log message.  I’ve used this class in each of the projects.

namespace ApplicationLifeCycle.Infrastructure {
    public class Logger {

        public static void Log(String notes = "") {
            StackTrace stackTrace = new StackTrace();

            String typeName = stackTrace.GetFrame(1).GetMethod().DeclaringType.Name;
            String methodName = stackTrace.GetFrame(1).GetMethod().Name;

            if(!String.IsNullOrEmpty(notes)) {
                notes = String.Concat(" - ", notes);
            Debug.WriteLine(String.Format("WP7: {0} - {1}{2}", typeName, methodName, notes));

        private Logger() {

LaunchersAndChoosers Project

This project demonstrates 3 launchers and 3 choosers.  It also provides a lot of logging so that you can see what goes on and when.  Spend some time, using the application.  Then predict the sequence of events before executing them, you’ll have the application lifecycle down quickly.

Take a look at the MainPage.xaml and MainPage.xaml.cs.  By using the CustomHyperlinkButtonStyle, I was able to run code-free in the code-behind.

TravelReporting Project

This application allows a user to enter a travel report from their phone.  The travel report has two pages of required data.  The user can’t proceed to the second page unless the first page is valid. 

For validation I’m using the declarative (attribute based) validation offered by the Ocean framework.  The validation API’s allow for multiple rule-sets.  This enabled me to have a set of rules for the first page’s fields and a set of rules to validate the entire object on page two.

IDataErrorInfo is not supported in this release of Silverlight for Windows Phone 7.  I have included the interface so that you can have it in place if and when it is supported.  In this simple application, I’m not bothering the user with messages until they press the Next or Save buttons.  When Next or Saved is pressed, the TravelReport object is validated against the appropriate rules.

To see the validation attributes in action, have a look at the TravelReport.cs file.  You’ll also see several rules added in code.

When the travel report is saved it is added to the history file. 

The History page  is accessed from the main page’s menu.  The history presents a list of travel reports and allows viewing the report in detail.

The history file simulates accessing the cloud for historical data.  When the application starts, two travel reports are added to the history file to give you something to look at.


TombstoneSupportPhoneApplicationPage (OceanFramework.Phone)

This is the base class for all my pages.  It adds automatic tombstone activating and deactivating support so that I don’t have to repeat this code on each page.

One challenge developers have is this business of focus not changing when the user presses the back, start, application button or menu.  The problem is, control data bindings do not update their source until lost focus occurs.  Since lost focus does not happen when the user does one of these actions, the user could loose that field’s data that was entered but not committed to the source.  Remember, when a user presses the start button, the application will be tombstoned and if the field’s data was not committed to the model or view model before those objects get persisted, then the data that was entered is lost.

Not to worry.  The below method handles this quirk for you.  Take note of the below TODO.  My current application only has TextBoxes that need this help.  Your applications may need additional tests for other controls.

This method also records the name of the currently focused control so that when the application comes back from tombstonning, the focus field can be restored.

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e) {

    // Remove previous focused element
    if (State.ContainsKey(FOCUSED_ELEMENT)) {

    // If an input control has focus, perform an explict binding update.
    // If the user pressed the back button, start button or application button,
    // the binding expression will not process since focus did not change.
    // So... you need to force the binding expression to update so that the
    // model property will be updated.
    var focusedElement = FocusManager.GetFocusedElement() as Control;
    if (focusedElement != null) {

        if (!String.IsNullOrEmpty(focusedElement.Name)) {
            State.Add(FOCUSED_ELEMENT, focusedElement.Name);

        BindingExpression be = null;

        //TODO - Developers, add additional controls here like a date picker, combobox, etc.
        if (focusedElement is TextBox) {
            be = focusedElement.GetBindingExpression(TextBox.TextProperty);

        if (be != null) {

IsolatedStorageFacade (OceanFramework.Phone)

This facade class provides a simple interface for interacting with the IsolatedStorageFile and IsolatedStorageSettings.  You’ll want to modify this to meet you specific needs.

I made all the methods static for ease of use.  If I was using an IOC container, I would provide an interface and inject an implementation.  This would also make testing easier since the implementation could be swapped out.

TombstoneFacade (OceanFramework.Phone)

This facade class provides a simple interface for interacting with the PhoneApplicationService temporary storage state bag.  You’ll want to modify this to meet you specific needs.

I made all the methods static for ease of use.  If I was using an IOC container, I would provide an interface and inject an implementation.  This would also make testing easier since the implementation could be swapped out.


I met with my great friend Laurent Bugnion of MVVM-Light fame this week and spent time taking about Windows Phone 7.  I asked him about globalization of the phone apps.  He explained his solution for using .resx files and I’m sharing it with you.

The Localizer class is a front end that we can instantiate in XAML, then controls can data bind directly to the properties in the .resx file.  This wrapper is required because the .resx class, can’t be instantiated in XAML, even if it is marked public.  This may be a bug, I’ll check up on this.

// Many thanks to Laurent Bugnion for this cool tip.
// This wrapper around the Strings.resx allows us to data bind to values in XAML
// See App.xaml and MainPage.xaml to see the moving parts.  Very simple solution.
public class Localizer {

    Strings _strings;

    public Strings Strings {
        get { return _strings; }

    public Localizer() {
        _strings = new Strings();

This XAML is from App.xaml.

<infrastructure:Localizer x:Key="LocalizedStrings" />

The below TextBlock displays a globalized string for the application title.  All strings in the TravelReports application are resources.

<TextBlock Style="{StaticResource PhoneTextNormalStyle}"
    Text="{Binding Source={StaticResource LocalizedStrings}, 
           Path=Strings.Application_Title, Mode=OneTime}" />


The download is on my sky drive here.

Remember after downloading a .zip file, you’ll want to right click on the file and “Unblock” the file.  This is the mark-of-the-web that Visual Studio 2010 respects.

Have a great day.

Just a grain of sand on the worlds beaches.

BBQ Shack – Ocean v2 for Visual Studio 2008

February 7, 2010

homepage What the Heck is BBQ Shack?

In September of 2009 I went on a cruise to Alaska with a simple goal of writing a WPF application that shared business objects and Ocean framework code with a Silverlight 3 project within the solution.  The WPF and Silverlight code sharing has since been made much easier.  Since Visual Studio 2010 Beta2, Silverlight 3 and 4 can easily share code with WPF;  I blogged how to do this here.

Before this cruise Jaime Rodriguez was encouraging me to quit writing line of business applications that looked and felt like Windows Forms applications.  He wanted me to start taking advantage of the capabilities of the WPF platform and not settle with an older UI paradigm.

Additionally, I felt challenged by the WPF work Billy Hollis did in 2008.  I strongly recommend that every WPF & Silverlight line of business application developer watch this challenging dnrTV video.

To my surprise, once I got aboard ship, I realized that two suite cases of Scope Creep got dropped off in my suite.  BBQ Shack began to grow into a medium size application requiring a lot of new Ocean framework features be coded on this cruise.

BBQ Shack was inspired by a real BBQ take-out, Outlaw BBQ Shack that is located in Matthews, NC.  If you are ever in the Charlotte, NC area you must visit the Outlaw BBQ Shack.  This small family owned business provided the BBQ for the Super Bowl XLI in 2007.

The BBQ Shack application story is; a software provider writes a WPF application that is initially used for manager functions, item maintenance and touch screen cash register software.  After a few months of use, the customer asks for a web presence.  So a Silverlight ordering application is deployed.  To save time and money, code reuse was critical.  (this is our scenario, not actual events in real life)

While the above story is just a scenario, I spent a good bit of time (and had fun) creating a data model that would allow me to have a very flexible way of maintaining inventory and understanding actual costs for products sold.

My goal for this blog post and the BBQ Shack application is to demonstrate the features in Ocean v2, while at the same time provide a real world MVVM line of business example.  Trying to reign in the scope, I did not write the Sales or Order Packing menu options nor the actual checkout screens.

I wrote 90% of BBQ Shack on the week long cruise, including a simple code generator for the business objects, business and data layer code.  After getting back from the cruise, I spent time with superstars Glenn Block and Jeff Handley.  They encouraged me to go back and make BBQ Shack IOC and test friendly.  Glenn and I also knocked around on a Friday evening for a few hours and wrote BLL(Of T) and DAL(Of T).  I refined that work and integrated it into BBQ Shack and Ocean v2.

In case you’re wondering, I used Expression Blend to create the above BBQ grill in XAML.

Table of Contents


The below links are to my Vimeo videos.  I have a short blog post here, that explains Vimeo and the features it provides you as a viewer.

I recommend that you view at least the first video before reading the blog post.  This will give you context and help your understanding of the application and Ocean API features introduced here.

BBQ Shack WPF version

BBQ Shack Silverlight version

Non-linear navigation deep dive

Ocean v2

I have created a home page for Ocean here.  Ocean v1, born on an Alaskan cruise in September of 2008 is the name for the framework I use for my application development.

Ocean v2 was created on my September 2009 Alaskan cruise along with the BBQ Shack.

See Ocean’s home page for more on Ocean v3.

BBQ Shack Features

I’m going to limit this blog post to the following feature list, otherwise I would never publish this work.  The videos at the bottom of the post will talk about every feature in BBQ Shack.

  • Non-linear application navigation with transitions
  • Task switcher
  • MVVM Modal & logging services
  • Master page concept forms
  • Background loading of all data
  • Business entity validation
  • BLL(Of T)
  • DAL(Of T)
  • Silverlight Code Sharing

While not a feature, Dan Dole a co-worker at Microsoft told me about a color pallet site called kuler.  I’ve long been told my UI’s don’t look so great.  I was trying to turn out a decent UI for BBQ Shack so I searched through the many color pallets at kuler.  BBQ Shack only uses a single pallet with 5 colors, along with black, white and a light gray.  Simple turned out to be best.

Non-Linear Application Navigation – View Manager Services

Billy Hollis used the phrase, “non-linear navigation” in the PDC presentation he did that was similar to the above dnrTV video.  The application he demonstrated was a product he wrote for his customer.  He spoke about the ability to hyperlink to any form or data record from anywhere in the application. 

Visualize Dashboard that presents a list of items that are low on inventory.  The ability to navigate directly to the item or another pertinent form is invaluable.  (yes sounds simple, keep reading)

Visualize some UI that presents the user a list of all active forms with the ability to navigate back to it from anywhere in the application.

WPF and Silverlight do not ship with baked in MDI support.  In my opinion this is good because it forces developers to design much better UI’s for their customers that don’t include countless little windows.

I also see non-linear navigation as a solution for end users that are required to multi-task to perform their job function.

BBQ Shack demonstrates non-linear navigation that allows a form to have a modal dialog displayed, slide that form out of the way to allow the user to perform another tasks and then easily navigate back to that task, just like users need to do in the real world.

BBQ Shack also provides 4 different animated form transitions that can be user selectable at run-time as part of a users profile if desired.

The below image pictures the list that is displayed when the user right-clicks on the circled “4” at the top of the Inventory button.  Clicking on one of the records will navigate the user directly to the form with that record.


When form is slide out of the way, it is not destroyed.  In fact it is running and can continue to run processes when its out of view.  This is one reason I listed background loading of all data in the features list.  If you process data access on the UI thread, you will severely limit your applications ability to provide multi-tasking features to your users and will also have issues with UI animation if the UI thread is also performing data access functions.  Background data access and processing solves this problem.

This non-linear, non-destructive feature really opens the possibilities for Silverlight 4 line of business applications.  Not forcing user to complete a form before being able to work on another form is a great UI feature.  This Silverlight feature will I ship with Ocean v3.1 for Visual Studio 2010 with Silverlight 4 support.  I need to wait until Silverlight 4 RTM’s before shipping any Silverlight 4 code.

The below image pictures the Inventory module with 4 active screens (4 includes the one pictured).  The user can easily see which forms are active with several options for getting to each one.  Notice in both the above and below images that the form state is displayed along with the record key and record title.


Consumers of business application software are experts in their vertical markets and are also very busy people.  Software that makes their job easier and transforms the computer from some sort of black box with a screen to a user friendly tool should be one of the goals of modern software developers.

The above search results have a unique feature.  The text of the result is a single click hyperlink to the record.  If the user clicks to the right of the text, that row will be selected and the Edit and Delete buttons will be enabled.

The below image shows a maintenance form with a modal dialog displayed.  The parent form is slightly grayed out while the application buttons at the bottom are not grayed out.  This allows for another application function to be carried out and then return to this form at a later time.   


Notice in the modal form the Item Base label is underlined.  This indicates that this is a hyperlink that when clicked will bring the Item Base Maintenance form into view, allowing that table to be modified.  When that Item Base form is closed, the application will come back to the above form in the same state it left it and will refresh the ComboBox data.

Notice the bread crumb trail under the form title of the above grayed out form.  This indicates to the user exactly where they are in the stack of forms.  If they were to click the Item Base hyperlink in the model window, the application would be navigated to the below form.  Notice the new breadcrumb and now the active forms goes from 4 to 5 in the Inventory button.


If you look the above images, you’ll see several common UI patterns. 

Save and Close buttons and the Add, Edit and Delete buttons.  In the video Billy Hollis spoke to simplifying our UI’s.  I’ve always been a Toolbar developer until now.  I like these buttons and believe end users will too.

Also notice the top of every form is the same.  This is just one of the free features available by using the master page concept form custom control.  See the below section for coverage of this feature.

How Does Non-Linear Navigation Work?

A single ViewManagerService exists for each application and is accessed through the IViewMangagerService Interface.  The ViewManagerService creates and controls one or more ViewManagers.  ViewManagers can only be accessed through the ViewManagerService.  The BBQ Shack has two ViewManagers, one for each Window in the application, ApplicationMainWindow and CashierView.

Accessing the ViewManagerService through the Interface enables IOC scenarios for object construction and makes unit/integration testing of the ViewModels very easy since mock objects can be injected.

Each ViewManager is responsible for keeping track of each form transitioned into and out of view and it also provides the hook for animating forms in and out of view.

The below ApplicaitonMainWindow.xaml has been stripped down to the bare essential to illustrate navigation concepts.

The Grid named applicationLayoutRoot is the Panel where all non-linear navigation will take place.



    <!-- ViewServiceManger loads/transistions all views here-->
    <Grid Grid.Row="1" x:Name="applicationLayoutRoot" />


The below code fragments are from the above ApplicationMainWindow.xaml code behind file and show how the BBQ Shack navigation is setup and how the application starts up.

The constructor is where the Grid applicationLayoutRoot is registered. The Add method creates a new ViewManager, assigns the Panel to it and provides the ability to hook into the form transitioning process.  This hook also enables platform specific transitions and for developers to create their own.  As you can see below I have provided four transitions for WPF applications with this version of Ocean.

Since the BBQ Shack is a navigation driven application, I have elected to have the Views create most of my ViewModels in the application as you can see in the last line of the constructor.  This is not a rule, it just made sense to me and simplified my application.

Private _objIViewManagerService As IViewManagerService = ViewManagerService.CreateInstance

Public Sub New()
    _objIViewManagerService.Add(Me.applicationLayoutRoot, AddressOf AnimateTransition)
    Me.DataContext = New ApplicationMainViewModel
End Sub

Private Sub AnimateTransition( _
    ByVal objCurrentView As FrameworkElement, ByVal objNewView As FrameworkElement)
    'TODO - developers - you can add a user preferences check here to select a different animation 
    '       or no animation
    'Call one of the below built in transitions or write your own.
    'Transistions.CreateInstance.NoTransition(Me, objCurrentView, objNewView)
    'Transistions.CreateInstance.DoublePaneRightToLeftTransition(Me, objCurrentView, objNewView)
    Transistions.CreateInstance.SinglePaneRightToLeftTransition(Me, objCurrentView, objNewView)
    'Transistions.CreateInstance.FadeTransition(Me, objCurrentView, objNewView)
End Sub

Private Sub ApplicationMainWindow_Loaded( _
    ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded    
    _objIViewManagerService.Select.Transition(Of HomeView)(My.Settings.HomeView, Nothing, _
                                                            strApplicationSuite:="BBQ Shack")
End Sub

All navigation functions are accessed through the IViewManagerService; this service manages the individual ViewManagers.  The Add method creates new ViewManagers.  The Select method returns a ViewManager.  The ShowWindow method provides a way for an application to launch a new window.  This allows your ViewModel’s to display a new window, either modal or non-modal.  Since the ViewManagerService will be mocked during unit/integration testing, the window will not actually open a new UI.


The ViewManager Transition method has the following capabilities:

  • Creates a new instance of a View if required
  • Can pass a primary key to the View; that View’s ViewModel will then look that record up for display
  • Can bring a previously open View into view
  • Can pass a DataContext to a View
  • Automatically handles multiple instances of the same form.  For example, the user could have two separate Person Maintenance forms adding new records and a third form editing a Person record
  • Meets one of my requirements which was to have the navigation work in a single line of code

Transition is the most used method of the ViewManager; it has five possible method signatures that are listed below.

Public Sub Transition(ByVal objNavigateKey As NavigateKey)

Public Sub Transition(Of T As {FrameworkElement, New})(ByVal strViewKey As String)

Public Sub Transition(Of T As {FrameworkElement, New})(ByVal objNavigateKey As NavigateKey, _
                                                       ByVal objDataContext As Object)

Public Sub Transition(Of T As {FrameworkElement, New})( _
            ByVal strViewKey As String, ByVal objDataContext As Object, _
            Optional ByVal objRecordPrimaryKey As Object = Nothing, _
            Optional ByVal strApplicationSuite As String = "")

Public Sub Transition(Of T As {FrameworkElement, New})(ByVal objNavigateKey As NavigateKey)

Before looking at each of the above overloads we need to understand the NavigateKey and its roll.


Each View managed by the ViewManager has a unique NavigateKey associated with it. When a new View is transitioned to a NavigateKey is created if a new one is not passed. 

The ParentNavigateKey is used by the ViewManager to navigate back to the View that opened a new View when the new View is closed.

If the RecordPrimaryKey is assigned, this can be used by the View/ViewModel to retrieve data and display it.

The Version property enables having multiple instance of the same View in the same state.  For example, the user opened the Person Maintenance View and is adding a record.  They then navigate to another form that allows them to open the Person Maintenance View again and add another record.  A customer service person could easily find themselves needing to do this.

When adding a new record the View’s RecordPrimaryKey will be null.  The Version is a simple Integer, that is supplied by the IViewManagerService NextVersion property.  Look back at the above IViewManagerService class diagram to see the NextVersion property.

The ViewKey is an application assigned string value.  I have put all my ViewKeys in the application settings.  You could also put them in a constants file.  Having constants ensures that your application won’t be a victim of a spelling mistake.

Transition Timing Cycle

When the Transition method is called, the following actions occur in the order specified:

  • Check if the requested View has been created, if not it will be created
  • Check if the requested View is the current view, if so stop further process
  • If the requested View is not contained in the registered Panel, add it to the Panel
  • Iterate all Views in the registered Panel and if not collapsed, set Visibility to Collapsed
  • Set the requested View’s Visibility to Visible
  • If the View implements INotifyOnBringIntoView, then call the OnBringIntoView method
  • If the View’s DataContext implements INotifyOnBringIntoView, then call the OnBringIntoView method
  • If the current View implements INotifyOnHidingView, then call the OnHidingView method
  • If the current View’s DataContext implements INotifyOnHidingView, then call the OnHidingView method
  • Set the current View’s ZIndexProperty to 0
  • Set the requested View’s ZIndexProperty to 99
  • Set the requested View’s Opacity to 1
  • Take a snapshot image of the requested View (used by the Task Switcher)
  • Invoke the animation callback that was registered, if no callback was registered then collapse the current View
  • Set the requested View as the current View
  • If the NavigateKey has a primary key value and the DataContext passed in the Transition method implements ILoadable then call the LoadRecord method
  • If the requested View was created and the requested View’s DataContext is implements ILoadable then call the LoadRecord method
  • If the NavigateKey has a primary key value and the View implements ILoadable then call the LoadRecord method
  • If a DataContext was passed in the Transition method, the assign that DataContext to the requested View.

The above is why I like the non-linear navigation API.  It handles so many actions that I would otherwise have to program and simplifies bringing a form into view down to a single line of code.

I also like the ability for Views and ViewModels to sign up for Load, UnLoad and LoadRecord notifications by implementing an Interface and overriding a method instead of responding to events and writing event handlers.

I’m hoping others will be inspired to create even better API’s and black box form management for WPF and Silverlight.  I’ve only got about 4 hours invested in design and coding this API.  It does meet my needs, but I’m sure there are other scenarios I have not taken into consideration.  I welcome all feedback and discussion on this topic.

Let’s have a look at each overload of the Transition method and see how it works and is used in BBQ Shack.

Transition Signature One

Public Sub Transition(ByVal objNavigateKey As NavigateKey)

The above method signature is use to navigate to an existing View, typically from a list of active views.  If the NavigateKey is null or not found an exception is thrown.

_objIViewManagerService.Select.Transition(CType(param, ActiveView).NavigateKey)

The above line of code can be found in 8 locations in the BBQ Shack code where active Views are listed and the user can navigate to them by clicking on their hyperlink.  If you look above to the second image in this post, you’ll see a list of Views, when one is clicked the above code is executed.  The third image shows a list of active item records.  When the Lays chips item is clicked, the above line of code will run.

The ActiveView type is used to encapsulate an active view in lists.  The ActiveView type also provides a DataContext property that UI DataTemplates can consume to display data when the list is rendered.

Transition Signature Two

Public Sub Transition(Of T As {FrameworkElement, New})(ByVal strViewKey As String)

The above method signature is use to navigate to a View that does not perform record maintenance.  Examples of these types of forms are the the HomeView and Cashier MealSelectorView.  There will never be more than one instance of Views loaded using this method signature since there is no Version number or RecordPrimaryKey to differentiate the Views.

_objIViewManagerService.Select.Transition(Of HomeView)(Settings.HomeView)

_objIViewManagerService.Select(STR_CASHIER).Transition(Of MealSelectorView) _

The first line of the above code should now be familiar.

The second line is the same with a twist.  Notice Select(STR_CASHIER).  STR_CASHIER is a constant that is used to tell the ViewManagerService to use the ViewManager identified by the key that has a value returned by the constant STR_CASHIER.

Transition Signature Three

Public Sub Transition(Of T As {FrameworkElement, New})(ByVal objNavigateKey As NavigateKey, _
                                                       ByVal objDataContext As Object)

The above method signature is not used by the BBQ Shack.  However, the other Transition methods call this method internally in the ViewManager, except the first signature that does not need the services provided by this method.  If you study the code in this method signature and the PerformTransition method, you’ll have a full understanding of how the ViewManager provides its services.

Transition Signature Four

Public Sub Transition(Of T As {FrameworkElement, New})( _
            ByVal strViewKey As String, _
            ByVal objDataContext As Object, _
            Optional ByVal objRecordPrimaryKey As Object = Nothing, _
            Optional ByVal strApplicationSuite As String = "")

The above method signature is used twice in the BBQ Shack, both are listed below. 

_objIViewManagerService.Select.Transition(Of HomeView)( _
        Settings.HomeView, Nothing, strApplicationSuite:="BBQ Shack")

_objIViewManagerService.Select.Transition(Of InventoryView)( _
    Settings.InventoryMenuView, Nothing, strApplicationSuite:="Inventory")

It’s primary purpose is to load up a View and assign that View to an ApplicationSuite.

Transition Signature Five

Public Sub Transition(Of T As {FrameworkElement, New})(ByVal objNavigateKey As NavigateKey)

The above method signature is the most commonly found in the BBQ Shack.  This is used when you need open a View and create a new record, or navigate to a View and edit an existing record.

_objIViewManagerService.Select.Transition(Of ItemCategoryView)(_ 
    New NavigateKey(_objIViewManagerService.NextVersion, Settings.ItemCategoryView, _
                    Me.NavigateKey, Settings.Inventory))

The above code demonstrates navigating to a new instance of the ItemCategoryView and setting the Version property to the value returned by the NextVersion property.  This code is run when the Add button is clicked.

Notice the ParentNavigateKey is set to the NavigateKey property of the current ViewModel.

Settings.Inventory sets the application suite this View belongs to.

_objIViewManagerService.Select.Transition(Of UnitOfMeasureView)( _
    New NavigateKey(Settings.UnitOfMeasureView, _
                    CType(param, uom_UnitOfMeasure_FillSelector).uom_UnitOfMeasureIdent, _
                    New NavigateKey(Settings.InventoryMenuView), Settings.Inventory))

The above code demonstrates navigating to the UnitOfMeasureView, instructing the View/ViewModel to load the record with a primary key value equal to value of uom_UnitOfMeasureIdent.  This code is run when a record is selected from the search results listing (see third image above.)

The ViewModel that is calling this code does not have direct access to its Parent’s Parent NavigateKey, so I simply pass a new NavigateKey that will point to the Inventory main View (see third image above).

Settings.Inventory sets the application suite this View belongs to.

Injecting View Manager Services

The below two constructors from the UnitOfMeasureViewModel demonstrate how the BBQ Shack utilizes a default object construction used by the application at run-time, while at the same time exposing the ability to use IOC for object construction or inject mock objects for unit/integration testing.

This ability exists because only Interface types are used.  The first constructor does create concrete objects but those are immediately passed to the second constructor and only the Interface type is used.

Even if you are not using IOC, I would still recommend using this pattern in your MVVM applications to easily enable unit/integration testing.  Additionally, programming to an interface gives you long term flexibility and decoupling that later on you may wish you had.  Cost to do this up front is super cheap as opposed to changing a lot of code later on. 

''' <summary>
''' Default object construction, creates a default BLL and DAL
''' </summary>
Public Sub New()
    Me.New(ViewManagerService.CreateInstance, _
           ViewModelUIService.CreateInstance, _
           BLL(Of uom_UnitOfMeasure).CreateInstance)
End Sub

''' <summary>
''' Used for unit testing or if you want to swap out the default concrete BLL or DAL
''' The DAL is swapped out by passing in a BLL that has a swapped out DAL.
''' </summary>
''' <param name="objIBLL">IBLL(Of uom_UnitOfMeasure)</param>
Public Sub New(ByVal objIViewManagerService As IViewManagerService, _
               ByVal objIViewModelUIService As IViewModelUIService, _
               ByVal objIBLL As IBLL(Of uom_UnitOfMeasure))

    _objIViewManagerService = objIViewManagerService
    _objIBLLUnitOfMeasure = objIBLL

End Sub

Task Switcher


I originally released the Task Switch in this blog post and demonstrated it in this application blog post.  One of the readers of my blog asked me to port this code to work with MVVM applications.  When I added the View Manager Services to Ocean this was real easy to accomplish.

The BBQ Shack ApplicationMainWindow listens for the CTRL+TAB key combination and will display the above Task Switcher.  Users can click on the desired task to switch to or they can also keep pressing CTRL+TAB to cycle through active tasks and release the CTRL key to navigate to the selected form.

Try to make application navigation as easy as possible for your users.  They will appreciate your innovation and extra efforts in this space.

The XAML for the Task Switcher is pictured below.  As you can see its stacked on top of the applicationLayoutRoot, centered within Grid.Row 1.

<!-- ViewServiceManger loads/transitions all views here-->
<Grid Grid.Row="1" x:Name="applicationLayoutRoot" />

    Grid.Row="1" x:Name="ucTaskSwitcherControl" HorizontalAlignment="Center" 
    VerticalAlignment="Center" Visibility="Collapsed">
        <OuterGlowBitmapEffect GlowSize="8" GlowColor="#FF5A5A5A" />

MVVM Modal and Logging Services – View Model UI Services

Opening a modal dialog window using Window.ShowModal() in a ViewModel will send most seasoned MVVM developers into a rage.  (OK, I might have overstate their reaction, but not by much).

So what’s the MVVM developer to do?  Logically they know they have to put up error dialogs, file open, file save dialogs and folder selection dialogs.  But they also understand that using these dialogs will foul up unit/integration tests or make that task much more complex than it needs to be.

I’ve read several good solutions by fellow developers.  The one I present here works for me, is fully testable and as an added benefit I’ve added logging capabilities to the every dialog.

This service is managed just like the View Manager Services.  The service is passed as an Interface into the constructor of types that need its services.  See the code in the above section, Injecting View Manager Services for an example.

The ViewModelUIService provides a rich set of methods to display message dialogs, file and folder dialogs and to log messages.

The message dialogs are all wrappers around the Task Dialog custom control I wrote back in 2007.  The latest version is in Ocean v2.


The Task Dialog custom control mimics the Windows Vista Task Dialog appearance even on Windows XP.  It has the same capabilities and can show the same icons and test regions at the Task Dialog.  Until the .NET Framework provides a wrapper for the Task Dialog, this is a very good option.


Did you notice the Log event in the above class diagram?

If you want to enable the logging of dialogs, in application startup, add a handler for the Log event.  Logging user responses to dialogs in applications is invaluable.  The LogMessage method allows adding a log message without a dialog.

Private Sub Application_Startup(ByVal sender As Object, _
                                ByVal e As System.Windows.StartupEventArgs) Handles Me.Startup
    'TODO - developers - set up logging event handler
    'AddHandler _objIViewModelUIService.Log, AddressOf WriteLogToFile-Database-EventLog-Email-etc
End Sub

For unit/integration testing application startup would not normally run.  Instead, you can add this line of code to your test code to test logging.

The below line of code displays the delete confirmation dialog pictured above.  The (3) is the number of seconds the user will have to wait until they can click the Yes or No buttons.  While waiting, a ProgressBar shows the remaining time.

If _objIViewModelUIService.YesNoConfirmDelete(3) = CustomDialogResult.Yes Then

The below line of code demonstrates showing the end user an exception message.  The idea was to make common programming tasks very easy.  The below ExceptionDialog method creates a dialog with the correct dialog caption, buttons and message.  As a bonus, if the application is a debug build, the Stack Trace is placed in the Additional Text collapsible region of the dialog.


Master Page Concept Control

ASP.NET has had master pages since .NET 1.1 (Paul Wilson’s custom control for .NET 1.1. .NET 2.0 added them in the box).

Developers are always looking for ways to simplify the coding of their applications and reduce the need to repeat boiler maker code to a minimum.  Using a master page paradigm also makes it much easier to refactor and change the general appearance of your application without having to actually touch the individual forms.

The below XAML fragment is from BBQShackFormResourceDictionary.xaml and is the BBQShackForm custom control that acts as a master page control.

I wrote about the below AdornerDecorator that wraps the form in this blog post.  Basically, this is required when a form puts up UI Elements in the WPF Adorner layer and that UI is then taken out of view and then brought back into view.  Without this you’ll end up with turds in your adorner layer.

This custom control provides the nice inner and outer borders, form titles, breadcrumb trail and form background. 

    <Border x:Name="bdr" Style="{StaticResource formOuterBorderStyle}">
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" MinHeight="400" />
            <Border Style="{StaticResource formTitleBorderStyle}">
                    <TextBlock Text="{Binding Path=ViewModelFriendlyName}" 
                               Style="{StaticResource formTitleStyle}" />
                    <TextBlock Margin="11,0,0,0" Text="{Binding Path=BreadcrumbTrail}" 
                               Style="{StaticResource formBreadcrumbStyle}" />
            <Rectangle Grid.Row="1" Style="{StaticResource formBackgroundRectangleStyle}" />

            <!--Put the form below here-->
            <ContentPresenter Grid.Row="1" />    
            <!--Put the form above here-->


The below XAML fragment is from UnitOfMeasureView.xaml and is the Unit of Measure maintenance form.

UnitOfMeasureView is a UserControl that derives from EditFormViewBase.  This UserControl’s content is the above BBQShackForm custom control.  The custom control’s content is contained in the below Grid.  See the below image that boxes out the regions on a form.

<Ocean_MVVM:EditFormViewBase ...>
        <Grid Margin="11">
            <Grid KeyboardNavigation.TabNavigation="Cycle">
                <Grid.RowDefinitions ...>
                <Grid.ColumnDefinitions ...>

                    DateCreated="{Binding Path=uom_UnitOfMeasure.uom_DateCreated}" 
                    DateModified="{Binding Path=uom_UnitOfMeasure.uom_DateModified}" 
                    CreatedBy="{Binding Path=uom_UnitOfMeasure.uom_CreatedBy}" 
                    ModifiedBy="{Binding Path=uom_UnitOfMeasure.uom_ModifiedBy}" 
                    ErrorHeaderText="{Binding Path=ErrorHeaderText}" 
                    WatermarkMessage="{Binding Path=WatermarkMessage}" 
                    IDataErrorInfoError="{Binding Path=uom_UnitOfMeasure.Error}" 
                    ErrorMessage="{Binding Path=ErrorMessage}" 
                    UIValidationErrorMessages="{Binding Path=UIValidationErrorMessages}" />

                <Label Grid.Column="0" Grid.Row="1" Content="Id" />
                <Label Grid.Column="0" Grid.Row="2" Content="Title" />

                <TextBlock Grid.Column="1" Grid.Row="1" 
                           Text="{Binding Path=uom_UnitOfMeasure.uom_UnitOfMeasureIdent}" ... />
                <TextBox x:Name="txtuom_Title" Grid.Column="1" Grid.Row="2" Width="75" 
                         Text="{Binding Path=uom_UnitOfMeasure.uom_Title}” MaxLength="15"/>

                <Grid Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" 
                      Grid.IsSharedSizeScope="True" HorizontalAlignment="Right">
                        <ColumnDefinition SharedSizeGroup="Buttons" />
                        <ColumnDefinition SharedSizeGroup="Buttons" />
                    <Button Command="{Binding Path=SaveCommand}" Content="Save" ... />
                    <Button Command="{Binding Path=CloseCommand}" Content="Close" ... />

The FormStatusUserControl provides the FormValidationControl and the two icons on the right side of each form.

I could have added the FormStatusUserControl to the BBQShackForm master page control but chose not to.  At the time I wrote it, I wasn’t sure if I would have boxed myself in, so I kept them separated.  In my next application I may move this to the master page control.

The below image shows a box diagram of the form.  The white box shows the BBQShackForm’s area and how the Grid contents as nested within the BBQShackForm.  Notice the lack of form coloring in the above code.  The BBQShackForm control takes care of all form colors.  This is why I use the master page concept, so that most of my application layout structure and coloring is in one location.  It would be super easy for a developer to change the colors or application layout structure of an application that uses this pattern.


The FormStatusUserControl contains a FormNotification control and two image buttons.

The FormNotification control is similar to the ASP.NET ValidationSummary control.  If the form is valid, the WatermarkMessage is displayed as in the above image, Valid record.  Any errors reported by the Model or ViewModel are listed in the expanded view as pictured below.  The FormNotification can also display other messages like, Record Saved after a successful write to the data store.

This form validation and error reporting is free, and is part of the Ocean framework.  Go back and look at the above XAML.  You’ll notice the FormStatusUserControl has a number of properties that are data bound to the Model and ViewModel.  It is that easy.


The below blue “A” image button opens a form that allows a case correction rule to be added.  The end user scenario is, the user is editing a form and the current case correction rules have made an unwanted correction.  Without interrupting the users workflow or train of thought, they can click the “A”, enter the new rule and go right back to their task.  Try it, you’ll like it.

The below properties icon provides a Tooltip that displays the current record metadata.  I’ve always added the below four fields to all of my database records.  But most users don’t need to see this information on every form, so an inhanced Tooltip made the most sense.


Background Loading and Processing of All Data

Windows Forms, WPF and Silverlight UI’s are all single threaded apartments (STA).  The bottom line for you is that you can only access the UI on the same thread that created it.  This means that you can’t spawn an additional thread and have that thread interact directly with the UI.

Side note:  I’ve been thinking about a black box that would make UI programming easier and that would take full advantage of the multiple cores of the host machine without the programmer having to write additional code, manage threads or background workers. 

There has to be a way to get rid of the UI bottleneck so my 8 cores can all spring into action.  I need to go on another cruise!

Microsoft added the Systetem.ComponentModel.BackgroundWorker to the .NET 2.0 framework.  This class encapsulates spawning new threads, optionally getting progress reports and the final results of the work.

BBQ Shack uses the BackgroundWorker for all data access.  By accessing all data off the UI thread, the UI remains response and all animations can run smoothly.  Let me give you an example; in BBQ Shack when you click on a record in the search results, the current form is animated out of view, the new form is animated into view and at the same time the new form is making a call to the database to retrieve the required data.  If this was all accomplished on one thread, BBQ Shack’s performance and usability would be severely degraded.

If you have not programmed with Silverlight, you may not know that all data access must be on a background thread.  If you are planning to write “cloud hosted” applications, you’ll want all your cloud access  performed on a background thread.

If you have not checked out .NET 4.0 Parallel Programming do this today.  This fun and ground breaking computing.

The below code snippet is from the UnitOfMeasureViewModel.vb file.  It shows the minimum code required to use the BackgroundWorker.

LoadRecord is a method on my ViewModel base class.  When this method is called and a primary key of the correct type is passed in, the BackgroundWorker.RunWorkerAsync method is called.  This method will then raise the BackgroundWorker.DoWork event on another thread.  When DoWork has completed its task or an unhandled exception occurs, the BackgroundWorker.RunWorkCompleted event is raised back on the UI thread.  It is that simple, just more code needs to be authored and maintained.  (now you know why I want to create a black box to do this for me)

 Private WithEvents _objBackgroundWorker As New BackgroundWorker

 Public Overrides Sub LoadRecord(ByVal objRecordKey As Object)

     If objRecordKey Is Nothing Then
         Me.uom_UnitOfMeasure = _objIBLLUnitOfMeasure.CreateEntity

     ElseIf Not TypeOf objRecordKey Is Integer Then
         Throw New ArgumentNullException("objRecordKey", AppResources.RecordKeyWrongType)

         _objLoadKey = objRecordKey
     End If

 End Sub 

Private Sub _objBackgroundWorker_DoWork( _
         ByVal sender As Object, _
         ByVal e As System.ComponentModel.DoWorkEventArgs) _
             Handles _objBackgroundWorker.DoWork

     e.Result = _objIBLLUnitOfMeasure.Select(CType(e.Argument, Integer))
 End Sub

 Private Sub _objBackgroundWorker_RunWorkerCompleted( _
         ByVal sender As Object, _
         ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
             Handles _objBackgroundWorker.RunWorkerCompleted

     If e.Error Is Nothing Then

         If e.Result IsNot Nothing Then
             Me.uom_UnitOfMeasure = CType(e.Result, uom_UnitOfMeasure)

             _objIViewModelUIService.MessageDialog("Data Error", "Record Not Found", ...) 
         End If

     End If

 End Sub

Notice the very first line of code in the above RunWorkerCompleted method.  You must check the value of e.Error before doing anything else.  Any exceptions from the other thread will be in the Error property.

If no exceptions were thrown on the background worker thread, you can then check the value of e.Result and consume the result.  Remember RunWorkerCompleted is executed back on the UI thread.

Business Entity Validation

I’ve written about business entity validation here and here.  Most of the content in this Code Project article are applicable to Ocean as they have the same API’s.

All of the business entity objects in BBQ Shack are shared by the WPF & Silverlight projects.  All of the validation code is platform agnostic.

One of Ocean’s goals was to enable cross platform business entity objects.  That goal has been achieved.

This works in Silverlight because when I create the Service References, I choose to reused types instead of having the proxy generated code re-implement my types.  I strongly recommend that you never allow the proxy generated code re-implement your types, always reuses your types.

I have trimmed the below code snippet for purposes of illustration.

This c_Customer class is from the c_Customer.gen.vb file.  The .gen. is my naming convention for files that are code generated.  The c_Cusomter type is complete with the c_Customer.vb partial class.  I love that partial classes allow me to add code to types that are code generated.

I’ve used this naming convention in all business applications since my days with SQL Server 7.0.  Essentially it provides a unique name for each object in the database, including columns.  That uniqueness is inherited in my code. 

While it looks strange at first, it makes it SUPER easy to search for all instance of the Customer Email field in my database, including stored procedures, all .NET code, XAML or HTML files.

Behind delivering customer features, code maintenance is my #1 priority.  This naming convention has worked for me accomplish that goal.  You should do that works for you and your team.

<DataContract(Namespace:="Ocean")> _
Partial Public Class c_Customer
    Inherits BusinessEntityBase

    <DataMember(IsRequired:=True)> _
    <CompareValueValidator(ComparisonType.Equal, 0, RequiredEntry.Yes, RuleSet:=STR_INSERT)> _
    <CompareValueValidator(ComparisonType.GreaterThan, 0, _
                           RequiredEntry.Yes, RuleSet:=STR_UPDATE_DELETE)> _
    Public Property c_CustomerIdent() As Integer
            Return _intc_CustomerIdent
        End Get
        Set(ByVal Value As Integer)
            MyBase.SetPropertyValue("c_CustomerIdent", _intc_CustomerIdent, Value)
        End Set
    End Property

    <DataMember(IsRequired:=True)> _
    <CharacterCasingFormatting(CharacterCasing.ProperName)> _
    <StringLengthValidator(1, 20)> _
    Public Property c_FirstName() As String
            Return _strc_FirstName
        End Get
        Set(ByVal Value As String)
            MyBase.SetPropertyValue("c_FirstName", _strc_FirstName, Value)
        End Set
    End Property

    <DataMember(IsRequired:=True)> _
    <CharacterCasingFormatting(CharacterCasing.LowerCase)> _
    <RegularExpressionValidator(RegularExpressionPatternType.Email, RequiredEntry.Yes)> _
    Public Property c_Email() As String
            Return _strc_Email
        End Get
        Set(ByVal Value As String)
            MyBase.SetPropertyValue("c_Email", _strc_Email, Value)
        End Set
    End Property

In BBQ Shack I have chosen to use opt-in data serialization as evidenced by the DataContract and DataMember attributes.

It took me awhile to warm up to the DataContractSerializer as opposed to the default opt-out serialization added to .NET 3.5.  I’m now using the opt-in DataContract serialization for all my WCF applications.


All my business entity objects derive from BusinessEntityBase.  This class provides the plumbing necessary for deriving objects to have  property and object validation,  case correction of entity values, change notification, validation interfaces implementation and other features.

The MyBase.SetPropertyValue method provides the entry point to have data validated, case correction applied and change notification.

Applying Validation Rules

Validation rules can be applied as attributes to properties, in code as shared rules or in code as an instance rule.  I like using the attributes because they are super easy to code generate, the rule is physically near the property so that when I read a business entity’s code I can “see” everything related to this property.

There are .NET restrictions as to data an attribute can contain.  For example you can put a function in an attribute so creating a rule that states that the date entered must be before Date.Now() is not permitted.  This is where the ability to add a rule in code comes into play.

For a great example of this open the BBQ Shack file, ccc_CharacterCasingCheck.vb located in the BBQShack.BusinessEntityObject project.  Now expand the Methods region.  In the AddSharedValidationRules method, not only did I add a business rule, but pointed that rule to some code I wrote that is specific to this class and will never be used again.

Ocean provides a rich set of lines of business validation rules you can use.  However, if you need your own, writing them is very easy.

  • BankRoutingNumberRule
  • ComparePropertyRule
  • CompareValueRule
  • CreditCardNumberRule
  • DomainRule
  • InRangeRule
  • NotNullRule
  • RegularExpressionRule
  • StateAbbreviationRule
  • StringLengthRule

I have also designed the validation attributes to accept both Decimal and Date values in the attribute.  Normally you can’t do this because values of these types can’t be used in an attribute.  For one example of this look at the Sale_Item.vb file in the BBQShack.BusinessEntityObjects project.

Shared validation rules are rules that all instances of a type will use.  The first time a type is created, all shared rules are added to a dictionary for the type so you only pay the cost to parse the attributes once.

Instance validation rules are added each time an instance of an object is created.  There is an AddInstanceValidationRules method in BusinessEntityBase that deriving types can override and provide required implementation.

I strongly recommend that you look at every business entity class.  You’ll find many real world examples of business rules being applied.

Rule Set

In the above code, the first validation attribute has the RuleSet property set to STR_INSERT.  This rule will only be applied when the business object is in insert mode; the mode of the object is set by assigning the BusinessEntityBase.RuleSet property.

Apply Case Correction Rules

In the above code you’ll also notice the CharacterCasingFormatting attribute in use.  This attribute adds a shared rule that gets applied by the BusinessEntityBase when a property value is set.  The following rules are provided by Ocean.

  • None
  • LowerCase
  • OutlookPhoneNoProperName
  • OutlookPhoneProperName
  • OutlookPhoneUpper
  • ProperName
  • UpperCase

The case correction API also provides hooks for developers to inject their own application specific case correction rules.  BBQ Shack provides a UI for end users to do just that.

IBLL(Of T)  c# – IBLL<T>

Superstar Glenn Block and I were in one of our code jam sessions and the idea to get rid of boiler maker business logic layer and data layer code came up.  I had originally written BBQ Shack with concrete BLL and DAL types for each business object.  That is one standard way to code these layers that many developers use.  I like it because its very easy to code generate and extend later as required.

Glenn and I cranked up a new Unit Test project, using TDD wrote IBLL(Of T) and IDAL(Of T).  I spend a few evenings of refactoring, creating concrete types and changed BBQ Shack over to use these.  Bottom line was I deleted to directories of files.  Part of the refactoring was injecting the concrete implementation of IBLL(Of T) into my ViewModels.  The testing of my ViewModels can be against a database or with mock objects.  Like the View Manager Services the ViewModels can be created by IOC too.

The main purpose of IBLL(Of T) was to relieve the developer from coding the most common business and data layer functions that deal with data store operations (CRUD).  These would be consumed by other developer written business or data layer code.

Real World Example:  When a new Customer is added, the business layer must initiate adding 3 other records and updating 2 more.  The ViewModel would call a single method in a developer written business layer method.  That method would utilize the IBLL(Of T) methods when reading and writing to the data store.  In this example, the developer only had to code the “real” business logic and not boiler maker code.

Just a quick glance at the below Interface will show the basic methods most BLL’s have today.  This is one of the four Interfaces that make up the generic BLL API.

Public Interface IBLL(Of T As {IBusinessEntity, Class, New})

  Function CreateEntity() As T

  Function Delete(ByVal intKey As Integer, ByVal objTimeStamp As Byte(), _
                    Optional ByVal strProcedureName As String = "") As Integer

  Function Delete(ByVal strKey As String, ByVal objTimeStamp As Byte(), _
                    Optional ByVal strProcedureName As String = "") As Integer

  Function Delete(Of K)(ByVal Key As K, ByVal objTimeStamp As Byte(), _
                          Optional ByVal strParameterName As String = "", _
                          Optional ByVal strProcedureName As String = "") As Integer

  Function Insert(ByVal Entity As T, ByRef intNewIdent As Integer, _
                    Optional ByVal strProcedureName As String = "") As Integer

  Function Insert(ByVal Entity As T, Optional ByVal strProcedureName As String = "") As Integer

  Function [Select](ByVal intKey As Integer, Optional ByVal strProcedureName As String = "") As T

  Function [Select](ByVal strKey As String, Optional ByVal strProcedureName As String = "") As T

  Function [Select](Of K)(ByVal Key As K, Optional ByVal strParameterName As String = "", _
                            Optional ByVal strProcedureName As String = "") As T

  Function Update(ByVal Entity As T, Optional ByVal strProcedureName As String = "") As Integer

End Interface

The BLL(Of T) and DAL(Of T) by default use a naming convention to call the correct stored procedure for database operations and to property name the parameters in the stored procedure calls.  In the case where a specific or unconventional name is required, the Optional ProcedureName parameter can be supplied.

Let’s take a look at the IBLL(Of T).Update method being called in a ViewModel.

Notice that the business object IsValid method is being called before Update is called.  If the IsValid method returns false, the ErrorHeaderText property is set to Save Errors. 

I always call the IsValid method in every layer of my code.  Doing this in the UI, ViewModel, BLL and DAL ensures that an invalid object never gets consumed.  Individual layers should be programmed defensively and never trust other layers (developers; LOL). 

Private Function Update() As Integer

        Me.uom_UnitOfMeasure.uom_DateModified = Now
        Me.uom_UnitOfMeasure.uom_ModifiedBy = Data.UserName

        If Me.uom_UnitOfMeasure.IsValid Then

            If _objIBLLUnitOfMeasure.Update(Me.uom_UnitOfMeasure) = 1 Then
                Return 1
            End If

        End If

        Me.ErrorHeaderText = "Save Errors"

    Catch ex As Exception
    End Try

    Return 0
End Function

If you are new to WPF the purpose of setting the above ErrorHeaderText property or how it works may not be obvious. 

If you look back to the above XAML for the UnitOfMeasureView UserControl, you’ll notice that the ErrorHeaderText property on the FormNotification control is data bound to the DataContext’s ErrorHeaderText property.  This property has built-in change notification, so that when the value is assigned in a ViewModel, that value is automatically consumed by the UI.

This is one of programming paradigm differences between WPF and other UI technologies.  In WPF or Silverlight we set properties in data that is bound to the UI.  In other UI technologies, we would normally set a property on a control in the UI.  The WPF pattern is much easier to program and when you adopt MVVM is much easier to unit/integration test.

The actual call to the business layer is done through the Interface and is a single line of code, wrapped in a Try Catch block.  Any errors are reported to the end user and are logged by the method call to the View Model UI Service in the Catch block.

Ocean provides concrete implementations for each of the business and data layer Interfaces that make up the IBLL(Of T) and IDAL(Of T) story.  These concrete implementations are coded the way I would program my layers.  You can easily rewrite them to comply with how you do things, or you can just inject your own concrete implementations of the Interfaces.  You are not locked into doing things the way I do, not at all.

Below is the default concrete implementation of the BLL(Of T) provided by Ocean.  DAL is a private property of type IDAL(Of T).

Public Function Update( _
    ByVal Entity As T, _
    Optional ByVal strProcedureName As String = "") As Integer Implements IBLL(Of T).Update

    Return DAL.Update(Entity, strProcedureName)
End Function

There are many very solid and wildly accepted reasons for layering your applications. One is that it enables the swapping out of data layers without having to change your application Views or ViewModels.

If I wanted to move my data store from a local SQL Server database to Azure or to SQL Server Compact or to a WCF Service, I would only have to provide a different concrete implementation of IDAL(Of T) and recompile. 

Heck, you could even just make that a config setting, have your IOC pick it up and with the flick of a user setting, change the data store.  Now you really understand why programming asynchronous data access up front is a must; it provides your applications the flexibility they need to meet the ever changing technologies we work with.

IDAL(Of T)   c#- IDAL<T>

IDAL(Of T) is the lower application layer that IBLL(Of T) consumes to perform data store operations.  The UI or ViewModels would never call methods on IDAL(Of T) directly.

IDAL(Of T) has the same Interface methods as IBLL(Of T) so I won’t repeat that code.  There are a total of four matching Interfaces exposed by IDAL that are consumed by IBLL.

The concrete implementation of IDAL(Of T) provided by Ocean is programmed against SQL Server 2008.  To target other data stores all that is required is a new concrete implementation of IDAL(Of T).

The hardest piece of the puzzle to solve was the creation of the stored procedure calls.  Proper ADO.NET parameters must be created, in the case of BBQ Shack and the provided concrete DAL implementation I had to create SQLParameters.  This requires knowledge of the business objects data store characteristics.

In BBQ Shack, I used an attribute on the business object properties to provide the required metadata.  These were easy to code generate and the action of parsing the attribute only has to be done once.  There you go, that is the trade off.  Add a code generated attribute and I get to delete two directories of files that I’ll never have to maintain going forward. 

The below code snippet is from the uom_UnitOfMeasure.vb file in the BBQShack.BusinessEntityObjects project.

The DataColumn attribute provides all the required metadata for the concrete implementation of DAL(Of T) to create SQLParameters or other types of parameters.  DataColumn has other properties and overloads that are not used below.

With a quick glace at the below code snippet and you can easily determine the data store characteristics of each property. 

Did you notice the lack of Booleans being used in any of my attributes.  Spending a few extra minutes to create an Enum pays off big time with respect to code readability.

<DataColumn(ColumnType.Timestamp)> _
<NotNullValidator(RuleSet:=STR_UPDATE_DELETE)> _
Public Property uom_Timestamp() As Byte()
        Return _objuom_Timestamp
    End Get
    Set(ByVal Value As Byte())
        MyBase.SetPropertyValue("uom_Timestamp", _objuom_Timestamp, Value)
    End Set
End Property

<DataColumn(ColumnType.VarChar, 15)> _
<CharacterCasingFormatting(CharacterCasing.LowerCase)> _
<StringLengthValidator(1, 15)> _
Public Property uom_Title() As String
        Return _struom_Title
    End Get
    Set(ByVal Value As String)
        MyBase.SetPropertyValue("uom_Title", _struom_Title, Value)
    End Set
End Property

<DataColumn(ColumnType.Int, PrimaryKey.Yes, Identity.Yes)> _
<CompareValueValidator(ComparisonType.Equal, 0, _
                       RequiredEntry.Yes, RuleSet:=STR_INSERT)> _
<CompareValueValidator(ComparisonType.GreaterThan, 0, _
                       RequiredEntry.Yes, RuleSet:=STR_UPDATE_DELETE)> _
Public Property uom_UnitOfMeasureIdent() As Integer
        Return _intuom_UnitOfMeasureIdent
    End Get
    Set(ByVal Value As Integer)
        MyBase.SetPropertyValue("uom_UnitOfMeasureIdent", _
                                _intuom_UnitOfMeasureIdent, Value)
    End Set
End Property

Ocean provides its own data stack contained in the DataAccess class.  DataAccess provides many services like connection string management, connection management, functions with overloads for accessing ADO.NET data methods, concurrency violation notification and index violation notification.

The below concrete implementation of the Update method is from the DAL.vb file in the OceanFrameworkGenericLayers project.

It first performs standard sanity checks, then builds the parameters and finally calls the ExecuteNonQuery method in Ocean’s DataAccess class.

I had thought about caching the created parameters and then just update them, but in the end, this was easier and performance was not affected.

Public Function Update( _
    ByVal obj As T, Optional ByVal strProcedureName As String = "") _
        As Integer Implements IDAL(Of T).Update

    If obj Is Nothing Then
        Throw New ArgumentNullException("obj", "Business object was null")
    End If

    If obj.ActiveRuleSet <> STR_UPDATE Then
        Throw New InvalidOperationException( _
            String.Format("{0} using wrong ActiveRuleSet for update.  Current setting: {1}.", _
                      Me.EntityName, obj.ActiveRuleSet))
    End If

    If Not obj.HasBeenValidated Then
        Throw New InvalidOperationException( _
            String.Format("{0} has not been validated for update.", _
                    Me, EntityName))
    End If

    Dim da As DataAccess = GetDataAccess()
    Dim params As New List(Of SqlParameter)

    For Each kvp As KeyValuePair(Of String, DataColumn) In _

        If kvp.Value.IsDateCreated OrElse kvp.Value.IsCreatedBy Then
            Continue For
        End If

        If kvp.Value.Nullable Then

            Dim objValue As Object = obj.GetType.GetProperty(kvp.Key).GetValue(obj, Nothing)

            If objValue Is Nothing Then
                params.Add(BuildSQLParameter( _
                           kvp.Value.ParameterName, _
                           GetSqlDataType(kvp.Value.ColumnType), _
                           ParameterDirection.Input, DBNull.Value))

                params.Add(BuildSQLParameter( _
                           kvp.Value.ParameterName, _
                           GetSqlDataType(kvp.Value.ColumnType), _
                           ParameterDirection.Input, objValue))
            End If

        ElseIf kvp.Value.MaximumLength > 0 Then
            params.Add(BuildSQLParameter( _
                       kvp.Value.ParameterName, _
                       GetSqlDataType(kvp.Value.ColumnType), _
                       kvp.Value.MaximumLength, ParameterDirection.Input, _
                       obj.GetType.GetProperty(kvp.Key).GetValue(obj, Nothing)))

            params.Add(BuildSQLParameter( _
                       kvp.Value.ParameterName, _
                       GetSqlDataType(kvp.Value.ColumnType), _
                       ParameterDirection.Input, _
                       obj.GetType.GetProperty(kvp.Key).GetValue(obj, Nothing)))
        End If


    Return da.ExecuteNonQuery( _
            CommandType.StoredProcedure, _
            GetStoredProcedureName(Me.UpdatestrProcedureName, strProcedureName), _

End Function

I  have not used IBLL(Of T) or IDAL(Of T) in a production application.  BBQ Shack is the first application. 

What I like about it is that all my CRUD business and data layer implementation is its basically in two files instead of boiler maker code repeated in many files.

I know, jury is still out, but I wanted to share the concept with you.

Silverlight Code Sharing

If you look at the BBQShack.BusinessEntityObjects.Silverlight project you’ll see that all the files are linked to files in the BBQShack.BusinessEntityObjects project.

Now for the real benefit of code sharing with Silverlight.

Look at the Service Reference in the BBQShack.Silverlight project pictured below.  Notice that I provided specific hints for type reuse. 

By doing this, the proxy wizard did not re-implement my business objects and I can now take full advantage of all the code in my business objects.


I have written about Silverlight code sharing in this blog post.

System Requirements

  • Visual Studio 2008 with SP1  (I have not tried BBQ Shack on Visual Studio 2010)
  • Silverlight 3 Developer Version (not Silverlight 3 Beta, not Silverlight 4 Beta)
  • Note:  If you cannot create a Silverlight application in Visual Studio, you do not have the Silverlight Developer version installed.
  • SQL Server 2008 or SQL Server 2008 Express (select install from the 3rd or 4th column)


Sky Drive BBQ Shack Source Code, Database and Ocean v2  (opens page where three zip files are located.)

You must download all three of the zip files.  The BBQShack and Ocean zip files should be unziped in the same folder, like your \Projects folder.  After unzipping the folders will look like this:



Doing this will ensure that the Ocean projects can be found by the BBQ Shack solution.

After unzipping the above download zip files, you will have these folders in your projects folder.


Database Installation

The above BBQ Shack download includes the SQL Server database .mdf and .ldf files.

If you do not have SQL Server Express 2008 download it from this page.  Select the install from the 3rd or 4th column of the download page.

If you have a SQL Server 2008 you must “attach” the database to an instance of SQL Server 2008.

If you have SQL Server Express you either can either “attach” the database to an instance of SQL Server Express or you can use the file attachment method in your connection string.

Next you must change the connection string in the BBQShack project and the BBQShack.Silverlight.Web project. 

To do this double click on the “My Properties” icon below the project name in the Solution Explorer.  Select the Settings tab and edit the connection string “Data Source” property of the connection string.  You MUST do do this for BOTH projects.


BBQ Shack was a fun adventure that took me places (including Alaska) I never thought I would go.  I hope that you can learn from the code and that some of the innovation in this project provides inspiration and possibly adoption.

Have a great day,

Just a grain of sand on the worlds beaches.


Get every new post delivered to your Inbox.

Join 255 other followers