Blending the Sketchflow Action

Started a new Sketchflow Prototype in Expression Blend recently and documented each of the steps.  This blog entry covers some of those steps, which are the basic elements of any prototype.  I will have more information regarding design, prototype creation, and the process of the initial phases for development in the future.  For now, I hope you enjoy this short walk through.  Also, be sure to check out my last quick entry on Sketchflow.

I started off with a Sketchflow Project, just like I did in my previous entry (more specifics in that entry about how to manipulate and build out the Sketchflow Map).

Once I created the project I setup the following Sketchflow Map.

The CoreNavigation is a ComponentScreen setup solely for the page navigation at the top of the screen.  The XAML markup in case you want to create a Component Screen with the same design is included below.

[sourcecode language="html"] <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:pb="clr-namespace:Microsoft.Expression.Prototyping.Behavior;assembly=Microsoft.Expression.Prototyping.Interactivity" x:Class="RapidPrototypeSketchScreens.CoreNavigation" d:DesignWidth="624" d:DesignHeight="49" Height="49" Width="624"> <Grid x:Name="LayoutRoot"> <TextBlock HorizontalAlignment="Stretch" Margin="307,3,0,0" Style="{StaticResource TitleCenter-Sketch}" Text="A?t?chart Scorecards" TextWrapping="Wrap"> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseLeftButtonDown"> <pb:NavigateToScreenAction TargetScreen="RapidPrototypeSketchScreens.Screen_1"/> </i:EventTrigger> </i:Interaction.Triggers> </TextBlock> <Button HorizontalAlignment="Left" Margin="164,8,0,11" Style="{StaticResource Button-Sketch}" Width="144" Content="Scorecard"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <pb:NavigateToScreenAction TargetScreen="RapidPrototypeSketchScreens.Screen_1_2"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <Button HorizontalAlignment="Left" Margin="8,8,0,11" Style="{StaticResource Button-Sketch}" Width="152" Content="Standard Reports"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <pb:NavigateToScreenAction TargetScreen="RapidPrototypeSketchScreens.Screen_1_1"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </UserControl> [/sourcecode]

Now that the CoreNavigation Component Screen is done I built out each of the others.  In each of those screens I included the CoreNavigation Screen (all those little green lines in the image) as the top navigation.  In order to do that, as I created each of the pages I would hover over the CoreNavigation Object in the Sketchflow Map.  When the utilities drawer (the small menu that pops down under a node when you hover over it) shows click on the third little icon and drag it onto the page node you want a navigation screen on.

Once I created all the screens I setup the navigation by opening up each screen and right clicking on the objects that needed to point to somewhere else in the prototype.

Once I was done with the main page, my Home Navigation Page, it looked something like this in the Expression Blend Designer.

I fleshed out each of the additional screens.  Once I was done I wanted to try out the deployment package.  The way to deploy a Sketchflow Prototype is to merely click on File ?> Package SketchFlow Project and a prompt will appear.  In the prompt enter what you want the package to be called.

I like to see the files generated afterwards too, so I checked the box to see that.  When Expression Blend is done generating everything you?ll have a directory like the one shown below, with all the needed files for deployment.

Now these files can be copied or moved to any location for viewing.  One can even copy them (such as via FTP) to a server location to share with others.  Once they are deployed and you run the “TestPage.html” the other features of the Sketchflow Package are available.

In the image below I have tagged a few sections to show the Sketchflow Player Features.  To the top left is the navigation, which provides a clearly defined area of movement in a list.  To the center right is the actual prototype application.  I have placed lists of things and made edits.  On the left hand side is the highlight feature, which is available in the Feedback section of the lower left.  On the right hand list I underlined the Autochart with an orange marker, and marked out two list items with a red marker.

In the lower left hand side in the Feedback section is also an area to type in your feedback.  This can be useful for time based feedback, when you post this somewhere and want people to provide subsequent follow up feedback.

Overall lots of great features, that enable some fairly rapid prototyping with customers.  Once one is familiar with the steps and parts of this Sketchflow Prototype Capabilities it is easy to step through an application without even stopping.  It really is that easy.  So get hold of Expression Blend 3 and get ramped up on Sketchflow, it will pay off in the design phases to do so!

Part 1 Basic Webtrends REST Examples

In this entry I just want to cover some examples of how to connect to Webtrends DX Web Services.  The DX Web Services use REST as the architecture, providing simple URI based end points to connect to.  With the Webtrends SDK you can connect to these services with your account information.  Here are the basic steps to retrieve a profile list, the reports from one of those profiles, and then the report you want from that report list.

First step is to create a Webtrends User.

WebTrends.Sdk.Account.User webtrendsUser = new Account.User();
webtrendsUser.UserName = username;
webtrendsUser.Password = password;
webtrendsUser.AccountName = account;

After you create the Webtrends User, simple request a profile list by getting list of ProfileDefinition Objects.

List<WebTrends.Sdk.Profile.ProfileDefinition> profiles =
  WebTrends.Sdk.Factory.NavigationFactory.BuildListing(webtrendsUser);

Next you will want to grab a report based on the profile you are in and your credentials.

List<WebTrends.Sdk.Report.ReportDefinition> reports =
WebTrends.Sdk.Factory.NavigationFactory.BuildListing(profiles[i], webtrendsUser);

In the code above, i would equate to the specific profile you want from the retrieved list of profiles in the profiles list.  The common scenario is that one has pulled the profiles into a drop down, combo, or list box that the user can select.  Then when the user selects the specific profile that profile object can then be used to pull the List of ReportDefinitions.

Once we have the report definitions, all sorts of criteria can be added together to query for a specific report.  This is also were things can get a little tricky.  For instance, take a look at the code below.

WebTrends.Sdk.Factory.ReportFactory.CreateDimensionalReport(
    report.ID.ToString(), profiles[i].ID.ToString(), "2010m01", webtrendsUser);

The CreateDimensionalReport takes 4 parameters for this particular overload.  The report ID, profile ID, the Webtrends Date Format, and the Webtrends User Object.  There are a number of other overloads available within this factory’s method that allow for passing the specific REST URI, and other criteria to retrieve the report of your choice.  In the near future we will be adding some more to this method also, which will provide more flexibility without needing to use the full REST URI.

I will have more on this, so all you Coders out there using Webtrends DX Services, I hope this is helpful!  Enjoy.

HighBall Part Duex (#4) Patterns

Navigation of Highball Series Part #1 | Part #2 | Part #3 | Part #4

Here in part #4 I want to cover the final wire up I did to get the initial screens to show.  The other primary focus of this blog entry is to cover some of the architectural patterns behind what I have so far.  We haven’t touched upon testing this yet, primarily because I’m stepping through wiring both Silverlight & WPF with these libraries for the first time.  I’ve done the WPF before, but not both.  Soon enough, I’ll get back to good standard practice and get some tests done first.  But for now, here’s the low down on wiring up Silverlight and the architectural patterns so far.

Architectural Patterns & Ideas

Dependency Injection

This is one of interesting parts of the application, at least to me.  For many the dependency injection is endlessly confusing, but it comes in immensely helpful in getting things loosely coupled and all wired up.  Because even when you decouple things, they do have to get wired up again – it’s just the how that’s important.  Below is an example of a presenter in the schedule module that uses constructor based dependency injection.  Dig it?  I’ll have another follow up entry in the future about what and how Dependency Injection works, along with the respective Dependency Inversion, Inversion of Control, and all those other patterns.  For now, just now that this is how the view gets registered with the region that is responsible for displaying it when the application runs.

[sourcecode language=”csharp”]
public class ScheduleViewAllPresenter : IModule
{
private readonly IRegionViewRegistry regionViewRegistry;

public ScheduleViewAllPresenter(IRegionViewRegistry registry)
{
regionViewRegistry = registry;
}

public void Initialize()
{
regionViewRegistry.RegisterViewWithRegion("HighBallMainRegion", typeof(ScheduleViewAllView));
}
}
[/sourcecode]

In the code snippet above you’ll see in the initialize method that the view that is injected is registered to the particular region that it will be displayed in.  In the shell the view will be displayed in the region as shown below.

[sourcecode language=”xml”]

[/sourcecode]

Composite Modules

I’ve added a single module to the solution so far.  This module has two views & their respective presenters, which I’ll cover in the section below.  The module is simply a project, loosely coupled, that will provide a view and the presentation logic for that view to be injected into the shell upon some application logic.

The module itself isn’t so much a pattern but more an architectural piece of the application.  As I move forward on this project I’ll add more modules to the solution as functionality is needed.  Each module will have an isolated, or mostly isolated, business use.  The first example that I have is the HighBall.Interface.Modules.ScheduleModule.  I’ll be adding more, probably along these lines;  mileage tracking, vehicle inventory, driver check-in, driver route choice, etc.  Each having a particular part of functionality that will primarily be isolated to itself.

When the CAL is used within a development team the modules would most likely be split off to individual pairs in the case of Agile, or even entire teams.  In Agile parlance each module would be a number of user stories, or in the most simple form, a single user story.

View & Presenter, with no Model yet.

The view and presenter are where you get to see the Model View Presenter (MVP) first start to appear.  Eventually as I move forward there will be the model, and more elaboration on the view and presenter.  For now all we have is the view, which is just the xaml markup and the presenter which is responsible for registering the view in the registry, and initializing the view with a region that it would be displayed in.  As you can see above in the Dependency Injection example the presenter is very thin at this point.

So that summarizes the cut off point for my first basic release of HighBall.  Check out the code release, rant at me about deficiencies, and if you have any additional ideas or other elaborations you’d like to see please do comment.

Currently I’m researching how to put TDD into effect to build the presenters, views, and other composite pieces of this application.  My next entry will have several examples of unit tests that aren’t currently included in this release.  Until then, happy hacking (or coding).

HighBall Part Duex (#3) Wiring Up Silverlight

Navigation of Highball Series Part #1 | Part #2 | Part #3 | Part #4

In this part I’ll be covering wiring up Silverlight with an appropriate module similarly to what part #1 and part #2 covered for WPF.  What I want to show in this entry is basically the differences of each module and the difference in the startup shell.  The differences are however very minimal, which leaves me curious about abstracting some of this and removing the code duplication, or maybe I should say xaml duplication.

One of the things I did after the first two parts of this series is to add some more projects that I would need once wired up and ready to continue with other parts of the project.  First I added the respective test projects, the other Silverlight Module projects etc.

This brings me to one of the differences between the WPF and Silverlight Interfaces.  For the modules that will be used in the Silverlight Project you?ll need to add Silverlight Class Library Project as shown to the left.  The Silverlight Class Library Template adds various assemblies and other references that are needed for these modules to be used in Silverlight Applications.

At this time I added a project to match each of the WPF Modules I had added previously.  I created four, then basically created the exact same presenters and views for the Silverlight Module.  After all of this I ended up with the following solution explorer view ? check the image to the right.

The second differences is in the shells and boot strappers.

In the WPF application the shell has the following simple code to kick off of the shell.  I used ReSharper to remove the unnecessary assemblies and other references.

[sourcecode language=”csharp”]
using System.Windows;

namespace HighBall.Interface.Wpf
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bootstrapper = new HighBallBootStrapper();
bootstrapper.Run();
}
}
}
[/sourcecode]

What I ended up with was simple an OnStartup method overriding the Application Class method.  In this method is simply the base class call, instantiation, and the Run method to kick off the boot strapper.  This is very different then the slew of code needed for the Silverlight application bootstrapper startup.  Now keep in mind that most of this code is generated when you create the Silverlight Application.

[sourcecode language=”csharp”]
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Browser;

namespace HighBall.Interface.Silverlight
{
public partial class App : Application
{
public App()
{
Startup += Application_Startup;
Exit += Application_Exit;
UnhandledException += Application_UnhandledException;

InitializeComponent();
}

private void Application_Startup(object sender, StartupEventArgs e)
{
var bootstrapper = new HighBallBootStrapper();
bootstrapper.Run();
}

private void Application_Exit(object sender, EventArgs e)
{
}

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (!Debugger.IsAttached)
{
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}

private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e)
{
try
{
string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace;
errorMsg = errorMsg.Replace(‘"’, ‘\”).Replace("\r\n", @"\n");

HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight 2 Application " + errorMsg +
"\");");
}
catch (Exception)
{
}
}
}
}
[/sourcecode]

The only method that is really altered is the Application_Startup method.  Simply instantiate the boot strapper and call run.

Now that we have that take a look at the boot strappers themselves.  They each have some respective differences.  The WPF bootstrapper looks like this:

[sourcecode language=”csharp”]
using System.Windows;
using HighBall.Interface.Modules.Schedule;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.UnityExtensions;

namespace HighBall.Interface.Wpf
{
internal class HighBallBootStrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
var shell = new HighBallShell();
return shell;
}

protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new ModuleCatalog();
catalog.AddModule(typeof(ScheduleAddPresenter));
return catalog;
}
}
}
[/sourcecode]

The Silverlight bootstrapper is below:

[sourcecode language=”csharp”]
using System.Windows;
using HighBall.Interface.Modules.Schedule.Silverlight;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.UnityExtensions;

namespace HighBall.Interface.Silverlight
{
public class HighBallBootStrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
var shell = Container.Resolve();
Application.Current.RootVisual = shell;
return shell;
}

protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new ModuleCatalog();
catalog.AddModule(typeof(ScheduleAddPresenter));
return catalog;
}
}
}
[/sourcecode]

The one difference as one can see is the Silverlight Application sets the Application.Current.RootVisual to the application shell.  Again, one of those places that just screams code duplication.  That?s it.

In my next entry I’m going to do a real quick wrap up and then post the code for what I?ve worked through so far.

HighBall Part Duex (#02) Adding the Composite Application Libraries

Navigation of Highball Series Part #1 | Part #2 | Part #3 | Part #4

The first thing I did was go download the Composite Application Library Guidance.  The Patterns & Practices Group Page on the Composite Application Library is available also with more links and information.  The steps I took to get all the CAL stuff added went something like this.

  • I added the projects & test projects for;  Composite.Desktop, Composite.Desktop.Tests, Composite.Presentation.Desktop, Composite.Presentation.Desktop.Tests, Composite.UnityExtensions.Desktop, Composite.UnityExtensions.Desktop.Tests.
  • Then I added the Microsoft.Practices.ServiceLocation.dll to the 3rd Party Assemblies directory and fixed the references in the above projects.  Since I had literally copied them from the CAL directory that the installer places them, I had to fix up the references, but I had done so on purpose so that I’d know exactly what references what.

After adding that I setup a project for my first module named HighBall.Interface.Modules.ScheduleModule.  In this module I made a view called ScheduleAddView.xaml and a module called ScheduleAddModule.cs.  In the xaml view I added the following markup, which is identical to the markup I created for the ScheduleAdd.xaml in the previous blog post.

[sourcecode language=”xml”]
<UserControl x:Class="HighBall.Interface.Modules.ScheduleModule.Views.ScheduleAdd"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
Foreground="White" Background="Black">
<Grid x:Name="LayoutRoot" Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Margin="5,5,5,5" x:Name="textRoutes">Routes:</TextBlock>
<ListBox Margin="5,5,5,5" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ListBoxItem x:Name="routeOne" Content="WES Commuter Rail"></ListBoxItem>
<ListBoxItem x:Name="routeTwo" Content="9 Powell"></ListBoxItem>
<ListBoxItem x:Name="routeThree" Content="72 Killingsworth/82nd Ave"></ListBoxItem>
<ListBoxItem x:Name="routeFour" Content="590 Tacoma/Seattle"></ListBoxItem>
<ListBoxItem x:Name="routeFive" Content="Sounder Commuter Rail"></ListBoxItem>
<ListBoxItem x:Name="routeSix" Content="The Newark Light Rail Orange Line"></ListBoxItem>
<ListBoxItem x:Name="routeSeven" Content="The Newark Light Rail Blue Line"></ListBoxItem>
<ListBoxItem x:Name="routeEight" Content="The River Line"></ListBoxItem>
</ListBox>
<TextBlock x:Name="routeName" Margin="0,5,5,5" Grid.Column="1" Grid.Row="0" >Add New Schedule</TextBlock>
<StackPanel Grid.Column="1" Grid.Row="1" >
<TextBlock x:Name="frequencyIdentifier" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">Frequency Identifier</TextBlock>
<TextBox x:Name="textFrequencyIdentifier" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<TextBlock x:Name="startLocation" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">Start Location</TextBlock>
<TextBox x:Name="textStartLocation" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<TextBlock x:Name="startTime" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">Start Time</TextBlock>
<TextBox x:Name="textStartTime" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<TextBlock x:Name="endLocation" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">End Location</TextBlock>
<TextBox x:Name="textEndLocation" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<TextBlock x:Name="endTime" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">End Time</TextBlock>
<TextBox x:Name="textEndTime" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<TextBlock x:Name="scheduleStarts" Margin="0,5,5,0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top">Schedule Starts</TextBlock>
<TextBox x:Name="textScheduleStarts" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<TextBlock x:Name="scheduleEnds" Margin="0,5,5,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top">Schedule Ends</TextBlock>
<TextBox x:Name="textScheduleEnds" Margin="0,5,5,0" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text=""></TextBox>
<Button x:Name="buttonAddNewSchedule" Margin="10,10" Grid.Column="1" Grid.Row="1" Height="Auto" Width="Auto" HorizontalAlignment="Right" VerticalAlignment="Top" Content="Add Schedule"></Button>
</StackPanel>
</Grid>
</UserControl>
[/sourcecode]

In the code behind and the class file I added nothing at this time.  We?ll come back to that in a minute.

Once I created that I went back to the HighBall.Interface.Wpf project that I had created in the previous blog entry.  I then added a HighBallBootStrapper.cs class file to the project.  In that file I added the following code.

[sourcecode language=”csharp”]
using System.Windows;
using HighBall.Interface.Modules.ScheduleModule;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.UnityExtensions;

namespace HighBall.Interface.Wpf
{
class HighBallBootStrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
var shell = new HighBallShell();
shell.Show();
return shell;
}
protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new ModuleCatalog()
.AddModule(typeof (ScheduleAddModule));
return catalog;
}
}
}
[/sourcecode]

In the code behind of the App.xaml file I then added the following.

[sourcecode language=”csharp”]
using System.Windows;
namespace HighBall.Interface.Wpf
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bootstrapper = new HighBallBootStrapper();
bootstrapper.Run();
}
}
}
[/sourcecode]

Now that we?re wired up there, we move on to the last few steps.  The next step is to wire the module up so it will show up in the shell when it is launched.  So open up the ScheduleAddModule.cs class file and add the following code.

[sourcecode language=”csharp”]
using HighBall.Interface.Modules.ScheduleModule.Views;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Regions;
namespace HighBall.Interface.Modules.ScheduleModule
{
public class ScheduleAddModule : IModule
{
private readonly IRegionViewRegistry regionViewRegistry;
public ScheduleAddModule(IRegionViewRegistry registry)
{
regionViewRegistry = registry;
}

public void Initialize()
{
regionViewRegistry.RegisterViewWithRegion("HighBallMainRegion", typeof(ScheduleAddView));
}
}
}
[/sourcecode]

Before wrapping up I went ahead and added the remaining view into the module project that is still in the HighBall.Interface.Wpf project.  Now I have the ScheduleViewAll.xaml view in the HighBall.Interface.Modules.ScheduleModule project.  Just to make sure all the associations where correct I actually made the file and THEN copied all of the xaml into the new file.  That way everything gets generated correctly.

I did run into an odd scenario during working through this example.  I launched the application and everything showed up as it is supposed to, BUT, two application screens would pop up.  I fiddled around a bit more and ended up with a blank screen with my injection broken.  Eventually I got it working but it was really odd regardless.

In my next entry I’ll be getting into describing the nuts and bolts of what is going on so far to provide some context.