Tech Blog

Jay's Technical blog

Hooters Mosaic App - Initial Info

23 June 2010
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I gotta share the cool app I've been working on for the last month (since it is live today). It's a mosaicof the Hooters logo containing pictures of Hooters girls for their Beauty Pageant (it also has various other hooters related pictures in the mosaic.. more on that in a minute). It is Facebook-enabled so if you don't do Facebook you won't be using this app. Within the mosaic you can search for a girl or simply press next and it will take you to each of the girls, bring up her bio and other information, and will provide you with a vote button (which you can do once a day). If you are browsing around and stop with a contestant (they have orange borders and hooters logos on them) in the middle of the screen (and there aren't that many other girls around.. in other words the picture should be somewhat zoomed in so that it's a decent size on screen), the voting controls/bio will popup. The Silverlight app tracks where you are in the app. Every time you go into the app, it randomizes the order of the girls, which we did to make it fair for the girls.

The mosaic itself is made up of over 10,000 images (although we didn't have that many to work with). We ended up duplicating the images multiple times in our mosaic (for instance each contestant is in the mosaic 6 or more times). We also provided some filler images in the mosaic of 2009 Beauty Pageant as well as pics of girls from various months pics in the Hooters Magazine as well as advertisements (so not all the girls in the mosaic are contestants). See if you can guess how many pics we actually have in it (excluding duplicates).

The backend (non-Silverlight) stuff is Azure (and needs to be). It also uses ASP.NET MVC and the Azure-Facebook toolkit created by Thuzi (,y employer).

Here's the link (again): Hooters Pageant App

I'll be showing this off at the next Tampa Bay Silverlight User Group this month (before John Papa tales over), and there are a few secrets that I'll share then. Over the coming months I'll be sharing some insights I learned about the MultiScaleImage control (the heart of Silverlight's DeepZoom Technology), and how I was able to implement a MVVM (pronounced "ViewModel") within a DeepZom app. The first real talk that I give on this topic will be at Pasco .Net next month.

BTW, here's what the app looks like:


Analysis of My SL4 Navigation Template with MVVM Light (plus 1 more template)

03 May 2010
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

In my last post I offered a MVVM Light version of the standard Navigation Template in Silverlight 4 (There’s an updated version at the bottom of this post). In this post I will I want to walk you through all the interesting things found in this template (it is in and of itself a learning tool). In fact this template contains a much fuller example of various techniques that you may want to employ.

As mentioned in our last installment you need to make sure you have MVVM Light installed properly. Additionally you need the 2 templates attached to this article (I have re-attached the original project template and a new item template to this post) unblocked, and placed in the appropriate places in your vs2010 templates directory (My project template is in “c:\Users\{UserName}\Documents\Visual Studio 2010\Templates\ProjectTemplates\Silverlight\Mvvm” and the item template is in “C:\Users\{UserName}\Documents\Visual Studio 2010\Templates\ItemTemplates\Silverlight\Mvvm”

Directory Structure

Probably the first thing you notice is that there are a couple new directories. Along with Assets and Views there is a ViewModel, a Model, and a Controls folder.

ViewModel Folder

If you open the ViewModel folder you will see classes that correspond to the XAML files in the views folder with 2 exceptions:

  1. The ErrorWindow.xaml doesn’t have a ViewModel for a number of reasons not the least of which is that it’s an error window we want to keep that fairly simple (it’s launched by the Application); if something were wrong with our ViewModel structure then no Error Message would appear – we wouldn’t want that to happen.
  2. There is a ViewModelLocator class in the ViewModel folder which has no XAML file. If you don’t know what this is you may want to read one of the getting started posts on the Laurent Bugnion’s MVVM Light site.
MainPageModel (ViewModel)/MainPage.xaml Enhancements

This page uses RelayCommands (an implementation of the ICommand interface) to bind the various clicks and actions to functions in our ViewModel. Here’s a snippet from the Commands region of the file (I laid these out into regions to make it easier to hide this code).

  1:public RelayCommand<NavigationEventArgs> NavigateCommand
  2: {
  3:     get;
  4:private set;
  5: }
  6:publicvoid NavigateAction(NavigationEventArgs e)
  7: {
  8:foreach (var link in AllNavLinks)
  9:     {
 10:         link.LinkIsActive = link.URIPath.Equals(e.Uri.ToString(), StringComparison.InvariantCultureIgnoreCase);
 11:     }
 12:
 13: }

Normally you would use the regular non-generic RelayCommand, but in this case (actually in both cases in this class) our code is setting up to handle an Event which does not provide a Command property we can bind to. MVVM Light provides us with a handy dandy Silverlight behavior (I think it’s a behavior) that we can bind to in our XAML. Here’s the XAML snippet (from MainPage.xaml) that pertains to this:

  1:<i:Interaction.Triggers>
  2:<i:EventTriggerEventName="Navigated">
  3:<cmd:EventToCommandCommand="{Binding NavigateCommand, Mode=OneWay}"
  4:PassEventArgsToCommand="True"/>
  5:</i:EventTrigger>
  6:<i:EventTriggerEventName="NavigationFailed">
  7:<cmd:EventToCommandCommand="{Binding NavigationFailed, Mode=OneWay}"
  8:PassEventArgsToCommand="True"/>
  9:</i:EventTrigger>
 10:</i:Interaction.Triggers>

Lines 2-5 are where we are identifying the event (line 2) and then we are binding the event to a command and telling it to pass the event arguments (3 and 4). Line 5 simply closes the tag. Lines 6-9 hook up the NavigationFailed event to another RelayCommand in our ViewModel.

In the constructor, we see the following code in the MainPageModel (ViewModel) class:

  1: AllNavLinks = new ObservableCollection<NavigationLinkInfo>();
  2: AllNavLinks.Add(new NavigationLinkInfo { NavText = "home", URI = "Home", IsFirstElement = true });
  3: AllNavLinks.Add(new NavigationLinkInfo { NavText = "about", URI = "About" });
  4: NavigateCommand = new RelayCommand<NavigationEventArgs>(
  5:     (e) => NavigateAction(e),
  6:     (e) => true);
  7:
  8: NavigationFailedCommand = new RelayCommand<NavigationFailedEventArgs>(
  9:     (e) => NavigationFailedAction(e),
 10:     (e) => true);

Lines 4-6 (and lines 8-10) sets up the glue for the RelayCommand <T>which will not only provide a connection to the method that actually fires (Lines 5 and 9) , but also provides a way (lines 6 10) to notify the UI when a command should not be available (on a button this will automatically make it go into a disabled state). In the latter we have hard coded a true value here, but you could actually have a function here instead that runs some state check. I’m not sure if this will do the same thing for the actual navigation control, so test this out before you actually try to disable a navigation option.

This template actually provides a little more power over the state of the “hyperlinks” in the navigation. Lines 1-3 set up an observable collection of NavigationLinkInfo objects which is the class that the Navigation is actually bound to. This is one of the places where our version makes a few things easier than the standard MS Supplies Navigation template. Lines 2 and 3 set up 2 navigation links: home and about. If we had additional navigation items we would simply add a line here and we would be all set to go which is similar to what we get in the MS supplied template, but I personally prefer to do this in code (we could also retrieve this value via MEF or some other injection framework… so we have a lot more flexibility in my opinion.. more on the MEF option later).

There’s another section of code you will want to know about but more on that after we cover the NavigationLinkInfo and the NavigationControl.

NavigationLinkInfo (in the Models folder)

Here’s what the class looks like in the Class View of VS 2010:

image

If you look back at the code above the code in the MainPageModel provided the URI which left off the opening “/”. It also se the Navtext, and IsFirstElement. The URIPath is simply the URI with the opening “/” added back in (and is used to bind to our NavigationControl. IsFirstElement actually ties to the ShowNavRectable which is the separator between navigation links (the first one doesn’t need a separator.

This leaves us with the LinkIsActive and LinkVisualState properties which are related. Since for the most part the code simply needs to set a visual state the LinkVisualState will automatically set the appropriate value which will in turn end up bound to the VisualState of the hyperlink control in the NavigationControl (this is a big deal and it took me a bit to get this working). The LinkIsActive property tells the link that it is the current one. Under the covers this property sets the correct Visual State which in turn is picked up by the NavigationControl to identify that it should switch its hyperlink control’s visual state (making it look like it is highlighted or not highlighted).

NavigationControl (in the Controls folder)

As mentioned there is some cool stuff going on in the NavigationControl. When you open up the constructor you will see that we are doing some data binding in code to the various properties found in the NavigationLinkInfo class which will be the data context for every instance of this control. (this supplied by an ItemsControl in the MainPage.Xaml file).

The most interesting thing here is the code that exposes the CurrentState to the “outside world” (well outside this class):

  1:publicconststring CurrentStatePropertyName = "CurrentState";
  2:
  3:publicstaticstring GetCurrentState(DependencyObject obj)
  4: {
  5:return (string)obj.GetValue(CurrentStateProperty);
  6: }
  7:publicstaticvoid SetCurrentState(DependencyObject obj, stringvalue)
  8: {
  9:     obj.SetValue(CurrentStateProperty, value);
 10: }
 11:privatestaticvoid TransitionToState(object sender, DependencyPropertyChangedEventArgs args)
 12: {
 13:
 14:     NavigationControl c = sender as NavigationControl;
 15:if (c != null)
 16:     {
 17:         VisualStateManager.GoToState(c.hlink, (string)args.NewValue, true);
 18:     }
 19://else
 20://{
 21://    throw new ArgumentException("CurrentState is only supported on the Control type");
 22://}
 23: }
 24:
 25:publicstaticreadonly DependencyProperty CurrentStateProperty =
 26:            DependencyProperty.RegisterAttached(CurrentStatePropertyName,
 27:typeof(String),
 28:typeof(NavigationControl),
 29:new PropertyMetadata(TransitionToState));

Lines 1-10 and 25 define the CurrentState as a dependency property. I won’t claim to understand everything here, but line 29 will cause the TransitionToState method to be registered as a ProeprtyChanged callback which will fire when the property changes. When this happens the TransitionToState method (in lines 11-23) will set the hyperlink (hlink) control’s VisualState to the appropriate one.

The next result from this and the NavigationLinkInfo class is that all we have to do in our viewmodel is set whether a NavigationLinkInfo Object’s NavigationLinkIsActive property to true or false and the “Binding glue” does the rest.

Here’s what that code looks like in the MainPageModel class:

  1:foreach (var link in AllNavLinks)
  2: {
  3:     link.LinkIsActive =
  4:         link.URIPath.Equals(e.Uri.ToString(), StringComparison.InvariantCultureIgnoreCase);
  5: }

This code is in the routine that fires just after the user clicks a link. e.Uri is the equivalent of the URIPath value. This routine actually resets all the NavigationLinkInfo objects’ LinkIsActive property.

How Do You proceed From Here?

Actually from here to create a new Page simply use the provided Item Template to create a new page in the Views folder, use the provided MVVM Light template for creating a ViewModel in the ViewModel folder, and add the ViewModel info to the ViewModelLocator (using the MVVM Light provided snippet). None of this sounds drop dead simple.. especially if you aren’t really into separation of concerns, but if you do this your XAML files will be “blendable” which means your designers will love you!

The Future

I really do want to make this a little easier. My plan is to create another version of this template with MEF that does away with the need to modify the ViewModelLocator. I might try to see if there is an easier way to provide the Navigation. My ultimate goal is that i want to be able to get MEF to be able to add new Navigations via a downloaded assembly (but whether that gets ina  template or not remains to be seen).


MVVM Light Navigation Template

01 May 2010
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

A few days ago on Twitter I mentioned that I had created a template that incorporates MVVM Light and the VS2010/SL4 Navigation Template. Since that point there have been some discussion of whether Codebehind has simply moved to the VM. While I don’t necessarily think so, I start to worry if I may have “overdone” the templates. I’m going to go ahead and publish the templates (no worries there) for a number of reasons. It illustrates some techniques that I have had a hard time digging up (most notably how to bind the visual state of an element and have it change when the property changes). I also think my version has a better story for creating new tabs. I will write about this some more, but right now, I just want to get these out.

BTW, to install this take the zip file and put it into your “My Documents\Visual Studio 2010\Templates\ProjectTemplates\Silverlight\Mvvm” (or some folder under “My Documents\Visual Studio 2010\Templates\ProjectTemplates”).

Enjoy!

PS. I’m noticing some issues with this version of the template. I may need to repost it later once I discover what is happening. Code all seems to be the same, but the template doesn’t work. I will try to post later this weekend,

[Update: I fixed the template this morning! Enjoy]

File Attachment SL4 Nav App With MVVM Light


TampaSLUG Meeting is March 3rd, 2010(Tonight) with Greg Leonardo

03 March 2010
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]our next meeting is tonight at 7pm at the MS offices (check out the TampaSLUG site for more info). Greg is bringing a us a talk which should coincide nicely with the talk I gave last month (even if you missed last month Greg's talk is still for those of you who want to learn).  If you have a desire to learn Silverlight, but don't know where to begin, or simply just want to get some background in it. This is the group and night for you! .

Greg is really knowledgaeble about Silverlight so this night aims to be a really good evening.

We will have pizza and soda, so plan on coming! BUT, there is one thing you must do! Register here --> http://tampaslug310.eventbrite.com/

Also as usual there will be a social afterwards which is a good place to ask the Silverlight gurus those tough questions..

Wed, Feb 10, 2010: Basics of Building Silverlight Applications (For Business Devs)

09 February 2010
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

Tomorrow, is our next meeting at 7pm at the MS offices (check out the TampaSLUG site for more info). I want to stress that this is a very basic 101 type of talk. If you have a desire to learn Silverlight, but don't know where to begin, or simply just want to get some background in it. This is the group and night for you! The night will be focused on a couple topics, but it's mostly about building forms with Silverlight and binding data to those forms to make your life easier (SIlverlight is actually easier in many respects from what you are used to if you are a web developer).

BTW, I hear its the speaker's first presentation on Silverlight so at the very least it will be fun to see him sweat.

We will have pizza and soda, so plan on coming! BUT, there is one thing you must do! Register here --> http://tampaslug0210.eventbrite.com/