WynApse Home Page
Home    Blog    Contact       
Latest Article:
Read my CoDe Magazine Article
My Tags:
Hosted by:


3 Months FREE!

Ask me how to get 6 months free.

Running on ASP.Net 2.0

Lifetime Member:
Join Community Credit - I did!


web tracker

Over 1338892 Pages Served


Silverlight 1.0 OutlookBar Control







Later Changes

Two weeks to the day after I started the Ajax-enabled version of this code in my MasterPage, Michael Washington wrote to me that the code was broken in this article. All it took was him saying that and I knew what was wrong, and can't believe nobody else reported it!

The JavaScript from the MasterPage was interfering with the JavaScript for the article ... amazing that the MasterPage one works without problems...

So, I've not made any changes to the JavaScript or XAML displayed in the boxes below, but what I have done is modified all the XAML and JavaScript that's running this article to make it function alongside the other. The only changes I made were naming changes to avoid interference.

The code is different between this article and what you see working in the right-hand sidebar for one basic reason, and that is extensibility. This article is written with a limited set of buttons, known at design time and unchanging, so I can set that number as a tag in the main canvas. The MasterPage code is populated from the database and has no design-time dependencies.

Because the code in the MasterPage is tighter, I will make that code available in the Silverlight 1.0 Meets SQL Via ASP.NET Ajax and Web Services article hopefully later today.

Interesting adventure, and thanks Michael! -- visit Michael's DNN Silverlight Site here.


Day One Changes

Matt Casto posted to my blog about a problem with the original code for this application. He was able to give me positive directions on how to cause a problem when the mouse was pressed and moved away from the button artwork. As it turns out, I had seen this happen once, but didn't know what I had done, and couldn't repeat it. Apparently a QA team of 1 is less than desirable :)

After some messing around, the solution ended up being very simple, and was caused by a feature addition when I went from rectangles to artwork. I knew I wanted to to at least do Rollover images, and since I had no prior need for MouseLeave and MouseEnter (that I was aware of), I put those two messages on the Image not the container canvas.

When I then tried to use the MouseEnter and MouseLeave to release the mouse capture, the MouseMove on the container was interfering.

The Solution - Three Parts

The solution to this problem was in three very simple parts:
  1. Move the MouseEnter and MouseLeave messages from the Image object to the container canvas
  2. Modify the MouseEnter and MouseLeave JavaScript to drill down to the Image to set the Source
  3. Make a determination that if the cursor leaves the mouse while the mouse is pressed, it is considered off-canvas and release mouse capture. This was a very easy decision to make because moving the mouse up and down is already handled. Left and right motion can be considered off-button.
The JavaScript and XAML shown below have been updated to reflect these changes.

Thanks Matt!


Desert Code Camp III Presentation

On September 15, 2007 I presented the application above during an introductory talk on Silverlight 1.0. I posted the code that evening on my blog, and that same zip file is available with the "Download" link just below.

The purpose of this article is to showcase the control on my site and to expand a bit on the code for those that were not in attendance.

Download the source code

Preliminary Discussion

At Code Camp, I began the talk by finding out that between 1/4 and 1/2 of the people attending had either never tried Silverlight, or had poor results when they tried. The first part of my presentation was directly geared to them. In the download file, you will find 5 sub-folders named "one", "two", "three", "four", and "five". I discussed those in numerical sequence.

Folder "one" contains only an html file, nothing more. It is a place holder for what follows.

Folder "two" adds Silverlight to the placeholder html file by displaying a TextBlock on the page.

Folder "three" is where the real fun begins as I displayed a series of 'buttons' built from a canvas, a Rectangle, and a Textblock. The buttons have the ability of being moved up and down displacing the one(s) above or below.

Folder "four" extends the button paradigm into the 'outlook bar' paradigm with a drop-down menu.

Folder "five" is what I'm displaying above, and discussing below.


Design Requirements

Once I had decided I was going to do an Outlook-style Navigation bar, I 'test drove' a couple similar bars, such as the toolbar in Visual Studio. My idea was not to try to exactly copy anything, but gather ideas and build my own. Since I began with simply buttons, some of my 'design' was a holdover from then, and my goals were modified as I went forward leaving me with the following:

  • Clicking a button will open a menu, and close any (other) existing menu
  • Clicking the button on an open menu will close the menu
  • Buttons with or without attached menus can be moved up or down displacing those above or below
  • As Buttons are moved up and down they should move over the top of the staionary ones
  • The whole 'control' should be easily extensible, so no names should be coded into the JavaScript
  • Rollover images will be used, but no 'down' images to avoid nasty interaction with the button slide code

How the movement is handled

Sliding things around on a Silverlight Canvas is not a big deal. People call it drag and drop, but there's no 'drop' to it, since it's not really a classical 'drop-target' type of concept. Using Canvas.ZIndex as items are 'grabbed' can give a very nice slide-over effect, and that's what I did with this code. Everything is Canvas.ZIndex 0 unless it's being moved, at which point it becomes 1.

One of the things I was concerned about was how to deal with the up/down and keep track of where a button was 'agnostically' (is that a word?). I didn't want to have to deal with names in the JavaScript because that would make extending the NavBar difficult. After drawing 5 buttons on paper, and indexing them 0 through 4, I realized that I could use the Tag property of the object to keep track of the index for me. If I always kept the buttons in order 0 through 4 top-to-bottom, then it would make the code easier to manipulate.

If you look at the XAML below, at start time, the upper-most button is "SelectionOne", and it is Tag "0". The buttons and tags progress downward to "SelectionFive" and Tag "4".

Looking at the button movement from a very granular standpoint, it simply becomes:

  • If I'm moving up, then (Tag - 1) is the button above me, and only allow it if I'm Tag > 0
  • If I'm moving down, then (Tag + 1) is the button below me, and only allow it if I'm Tag < Last Tag
Rather than discuss this in a general case, let's consider SelectionFive is moved up to exchange places with SelectionFour. The sequence of events happens when the top edge of SelectionFive crosses above the top edge of SelectionFour:

  • SelectionFive is set to the position of SelectionFour
  • SelectionFour is pushed down below SelectionFive (and SelectionFive's menu if it is showing)
  • SelectionFive's Tag is decremented
  • SelectionFour's Tag is incremented
Downward movement is identical with the exception of dealing with the lower edge of the buttons crossing each other. It be