Schedules, Tickets, and Analysis? HighBall Thoughts

OLAP?

I got to thinking about my HighBall Project and thought, wouldn?t it be awesome to use some of my know how to wire up some serious cubes and analyze the results from site usage all the way to scheduling analysis?  It?s an idea, but I?m not really sure how I would do it yet.  I do however have some ideas in regards to scheduling and how a nice cube could be used to analyze effective scheduling usage.  Sounds like something TriMet could even use ? if they don?t already do these types of analysis.  ;)

Here?s my thought.

Take a schedule as the time dimension.  That?s simple enough.  Now take X number of routes as opposing dimensions and use ridership counts, peak load, etc as the fact table sums and such.  The data should align accordingly to the apex of routes and concentration of route needs by riders.  This type of data could be used to find out where ridership peaks and drops and how to fill gaps or even where to increase service.

?not really sure, got a ways to go before I try it, but it is an interesting thought for analysis.  Eventually I?ll give it a shot.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 4/22/2009 at 6:47 AM
Tags: , , ,
Categories: Business Intelligence and Analytics | Highball
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

HighBall Part Duex (#4) Patterns

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.

public class ScheduleViewAllPresenter : IModule
{
    private readonly IRegionViewRegistry regionViewRegistry;
 
    public ScheduleViewAllPresenter(IRegionViewRegistry registry)
    {
        regionViewRegistry = registry;
    }
 
    public void Initialize()
    {
        regionViewRegistry.RegisterViewWithRegion("HighBallMainRegion", typeof(ScheduleViewAllView));
    }
}

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.

<Window x:Class="HighBall.Interface.Wpf.HighBallShell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"
    Title="High Ball - WPF" >
    <ItemsControl Name="MainRegion" cal:RegionManager.RegionName="HighBallMainRegion" />
</Window>

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).

kick it on DotNetKicks.com
Shout it
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

HighBall Part Duex (#3) Wiring Up Silverlight

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.

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();
        }
    }
}

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.

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)
            {
            }
        }
    }
}

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:

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;
        }
    }
}

The Silverlight bootstrapper is below:

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<HighBallShell>();
            Application.Current.RootVisual = shell;
            return shell;
        }
 
        protected override IModuleCatalog GetModuleCatalog()
        {
            var catalog = new ModuleCatalog();
            catalog.AddModule(typeof(ScheduleAddPresenter));
            return catalog;
        }
    }
}

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.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: adron
Posted on: 4/12/2009 at 11:40 PM
Tags: , , , ,
Categories: Highball | How-To, Samples, and Such
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

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

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.

<UserControl x:Class="HighBall.Interface.Modules.ScheduleModule.Views.ScheduleAdd"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    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>

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.

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;
        }
    }
}

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

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();
        }
    }
}

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.

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));
        }
    }
}

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.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: adron
Posted on: 4/1/2009 at 6:50 PM
Tags: , , , ,
Categories: How-To, Samples, and Such | Highball
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

HighBall Part Duex (#01)

I'm working through this next part of my HighBall Project, which I'll be blogging regularly, using TDD and UI/X First Development.  In other words, to give some context, I'm building out a UI first, then I'll start from the back end and build together using primarily TDD style development.  I'll admit, I'm a bit unsure of how to go about building out the UI with a TDD style process.  But hopefully by the end of this little application building exercise I'll have it figured out.

My basic user stories so far is as follows.

  1. As a manager I want to create a schedule for a particular route.
  2. As a manager I want to delete an old schedule for a particular route.
  3. As a manager I want to view all of the schedules for all routes.
  4. As a manager I want to view the history of all past schedules for all routes.
  5. The driver needs to select a route and view the route schedule.

Basically we have the simple CRUD operations for a schedule tracking system.  I'll elaborate more as I work through this project.

For the first step I created the follow UI pieces in Silverlight & WPF, one for web and one for desktop.  Eventually I might even toss in the ASP.NET MVC for a non-Silverlight web version.  But for now the first step is to mock up the screens as the manager & drivers would view them.

Mocking Up the Screens

I created the create screen first to figure out how I would do this.  Keep in mind I'm going at this almost completely blind, as I'm not even sure what the actual architecture might be.  I'm merely giving both of these approaches a shot at the same time.  One last note, I'll be using TriMet, NJ Transit, and Sound Transit as my sources of example data, so if it seems familiar, it is.

The first view module that I built was the add route schedule screen.  Upon completion of the basic screen I was amazed at how similar the xaml was for the Silverlight and the WPF.  With this level of similarity I'm thinking there will be many more ways to refactor the xaml itself.  Maybe even create a xaml view generator?  At this point, the goal is to get the view modules created, so back to work.  Here is my first module below.  So far the WPF and Silverlight screen are exactly the same.

<UserControl x:Class="HighBall.Interface.Wpf.ScheduleAdd"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    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>

The next screen I built was the view all module.  Since I would most likely reuse this screen, or at least a large part of it, for the delete screen it would be best not to get the cart before the horse.

<UserControl x:Class="HighBall.Interface.Silverlight.ScheduleViewAll"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <ListBox x:Name="listSchedules">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="260" Text="{Binding Path=FrequencyIdenfitier}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="210" Text="{Binding Path=Route}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="100" Text="{Binding Path=StartLocation}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="100" Text="{Binding Path=EndLocation}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="140" Text="{Binding Path=ScheduleStarts}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="140" Text="{Binding Path=ScheduleEnds}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="80" Text="{Binding Path=StartTime}"/>
                        <TextBlock Width="Auto" Height="Auto" Padding="5" MinWidth="80" Text="{Binding Path=EndTime}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

To test out what it would look like I added the following class and code just for an example.

using System;
using System.Collections.Generic;
using System.Windows.Controls;
 
namespace HighBall.Interface.Silverlight
{
    public partial class ScheduleViewAll : UserControl
    {
        public ScheduleViewAll()
        {
            InitializeComponent();
 
            var schedules = LoadTestViewData();
            listSchedules.ItemsSource = schedules;
        }
 
        private static List<RouteSchedule> LoadTestViewData()
        {
            var schedules =
                new List<RouteSchedule>
                    {
                        new RouteSchedule
                            {
                                Route = "WES Commuter Rail",
                                EndLocation = "Beaverton",
                                EndTime = DateTime.Now.AddHours(-5),
                                FrequencyIdenfitier = Guid.NewGuid().ToString(),
                                ScheduleEnds = DateTime.Now.AddDays(185),
                                ScheduleStarts = DateTime.Now.AddDays(5),
                                StartLocation = "Wilsonville",
                                StartTime = DateTime.Now.AddHours(10)
                            },
                        new RouteSchedule
                            {
                                Route = "WES Commuter Rail",
                                EndLocation = "Wilsonville",
                                EndTime = DateTime.Now.AddHours(-5),
                                FrequencyIdenfitier = Guid.NewGuid().ToString(),
                                ScheduleEnds = DateTime.Now.AddDays(185),
                                ScheduleStarts = DateTime.Now.AddDays(5),
                                StartLocation = "Beaverton",
                                StartTime = DateTime.Now.AddHours(10)
                            },
                        new RouteSchedule
                            {
                                Route = "WES Commuter Rail",
                                EndLocation = "Beaverton",
                                EndTime = DateTime.Now.AddHours(-5.5),
                                FrequencyIdenfitier = Guid.NewGuid().ToString(),
                                ScheduleEnds = DateTime.Now.AddDays(185),
                                ScheduleStarts = DateTime.Now.AddDays(5),
                                StartLocation = "Wilsonville",
                                StartTime = DateTime.Now.AddHours(9.5)
                            },
                        new RouteSchedule
                            {
                                Route = "WES Commuter Rail",
                                EndLocation = "Wilsonville",
                                EndTime = DateTime.Now.AddHours(-5.5),
                                FrequencyIdenfitier = Guid.NewGuid().ToString(),
                                ScheduleEnds = DateTime.Now.AddDays(185),
                                ScheduleStarts = DateTime.Now.AddDays(5),
                                StartLocation = "Beaverton",
                                StartTime = DateTime.Now.AddHours(9.5)
                            },
                        new RouteSchedule
                            {
                                Route = "590 Tacoma/Seattle",
                                EndLocation = "Seattle",
                                EndTime = DateTime.Now.AddHours(-5),
                                FrequencyIdenfitier = Guid.NewGuid().ToString(),
                                ScheduleEnds = DateTime.Now.AddDays(185),
                                ScheduleStarts = DateTime.Now.AddDays(5),
                                StartLocation = "Tacoma",
                                StartTime = DateTime.Now.AddHours(10)
                            }
                    };
 
            return schedules;
        }
    }
 
    public class RouteSchedule
    {
        public string Route { get; set; }
        public string FrequencyIdenfitier { get; set; }
        public string StartLocation { get; set; }
        public string EndLocation { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public DateTime ScheduleStarts { get; set; }
        public DateTime ScheduleEnds { get; set; }
    }
}

While trying to get this to work in the Silverlight screen I ran into the dreaded "AG_E_INVALID_ARGUMENT" exception.  This is some type of xaml parsing issue, which I jumped right out to Google to try and figure out.  The link above eventually led me to this entry on the silverlight forums.  Even after digging through all of these ancient (in Silverlight terms) fixes, I still had the error.  At this point I threw up my hands and recreated the entire screen.  Once I did that, it worked.  However, the Silverlight xaml screen stopped color coding the xaml correctly and shaded out ALL of the ListBox.ItemTemplate xaml between the tags.  I don't know what is wrong with this but it is extremely annoying.

StringFormat is another thing that works in WPF but not in Silverlight.  I started to use them to format the date time bound fields.  Since there is this disparity, I just left that as is.  I'll eventually get back to cleaning up data a bit later.

At this point I needed to wire these together for the customer (which at this point is me, but I'm following Agile Practice).  I didn't want to get too many UI modules done and then realize I had to change significant parts.  In my next entry I'll cover working with the Composite Application Library (used to be the Composite Application Block, but that's evil) to get two builds, one for Silverlight and one for WPF.

Other bits of Information relating to user stories, UI/X, TDD, and other topics.

Of course, grab the code on Codeplex for HighBall.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: adron
Posted on: 3/30/2009 at 7:35 AM
Tags: , , , ,
Categories: How-To, Samples, and Such | Highball
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

Open ID Providers for .NET Part 1

OpenID is sweeping the web. With announcements by Microsoft and Google recently to support the OpenID Framework, things have effectively gotten huge! One of the things I've been wondering about is WCF Security and how one could integrate with OpenID. Here's what I've been able to dig up and implement so far.

First off, it is a good idea to review what OpenID is. Check it out at openid.net for a starting point. A good read is available at the what page for OpenID. However, if you want to get into the nitty gritty internal workings of OpenID, it is a little trickier. The developer page is a good place to start, but it is somewhat minimal. Once jumping out from that page the information gets more useful. Plaxo has an interesting recipe for OpenID and also OpenID for non-Super Users are great. Both get into the grit more.

But skipping past a ton of the existing specifications and documentation might be a better idea once I realized that there truly were some .NET libraries for Open ID.

Out of these two examples ExtremeSwank definitely has the best documentation out. Easy to read code examples are even available. I started to just go with ExtremeSwank, but after looking up integration notes on OpenID support in BlogEngine.NET I decided to download both.

For my pending BlogEngine.NET Integration I found the following articles:

I'll have the follow up to my discoveries soon, so stay tuned!

...and if you do want to read the specifications, feel free.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: adron
Posted on: 11/11/2008 at 7:12 AM
Tags: , , ,
Categories: Highball | How-To, Samples, and Such
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

WCF, Certificate Issues, and Stackoverflow

I've been working on getting certificates setup for development with the WCF Web Services I'm building for the High Ball Project.  On a few topics I'm just completely new, like messing with the Certificates, X.509 and SSL and such.  I'm getting there, but road blocks are stopping me every once in a while.  One of my recent issues was how to view the values that the certificate has.  I searched and searched, for some reason I couldn't find something on MSDN or via Google that would do what I wanted it to do.  In addition to that, the reason I was looking for this application to begin with, I was having issues with getting my web.config settings correct for finding the local certificate I had created with makecert.exe.

Stack Overflow!

That's when it clicked in my head, hey, I should try this stackoverflow site out!  So I shot over there and posed these two questions and within less than a 24 hr period on the WEEKEND, I got some solid answers.  I gotta say the guys over at stackoverflow are onto something here!

My first question, "Cannot find the X.509 Certificate using the following search criteria:..." and second question "Tool for Viewing X.509 Certificates?" have two great answers.  So check em' out, and if you aren't signed up with an OpenID get one and go log into the site!  It rocks.  In addition, for you dot netters out there like me, know that the site is built on ASP.NET MVC!  It's solid and FAST!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 10/19/2008 at 11:50 AM
Tags: , , , ,
Categories: Highball | My Projects | Website and Application Write-Ups
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Solution Layout for High Ball

I added a graphic of the solution layout of the High Ball Application with some basic descriptions of the various sections.  I do want to however reduce the number of projects inside the solution, but for now I've left it in the very separated out way I initially created the solution.

My next idea is to get some initial views done to use as a starting point for functionality.  I'd like to complete the security administration section soon, so the other parts of the application can be further fleshed out.  I will admit though, I'm not 100% sure how I want to setup the security, and am currently brain storming the idea.  If anyone would like to jump in on that lemme know.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 9/21/2008 at 7:34 PM
Tags: , , , ,
Categories: My Projects | Transit Engine | Highball
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed