Back To: Silverlight Tutorials
This is "Yet Another Silverlight Toolbar". What sets this toolbar apart is that it is composed of only a Toolbar and a Box. The box is simply placed in the toolbar multiple times to create the elements on the Toolbar.
This shows the files in the project. The application is primarily composed of Page.xaml that contains the toolbar and Box.xaml that contains the element used to represent the menu items.
The picture above shows how the toolbar looks when viewed in Expression Blend. All the elements are easily editable. Basically it is comprised of a ToolBar that scrolls to the left and the right. The JavaScript method (SetToolbarWindowClip) will apply a "Clip" that will only show a portion of the Toolbar.
The graphic above shows the outline of the elements.
As you can see the Box.xaml file is simply an image with a reflected image below it. This file is also easily editable in Expression Blend.
The animation is simple and straightforward. Page.xaml contains a storyboard:
<Canvas.Resources>
<Storyboard x:Name="Movebar">
<DoubleAnimation x:Name="animateToolbar" Duration="0:0:0.5"
Storyboard.TargetName="ToolBar"
Storyboard.TargetProperty="(Canvas.Left)" />
</Storyboard>
</Canvas.Resources>
storyboard = rootElement.findName("Movebar");
animation = rootElement.findName("animateToolbar");
animation.To = scrollPosition;
storyboard.Begin();
//Array of pictures
var objPicture = new Array();
objPicture[0] = "adef.png";
objPicture[1] = "bells.png";
objPicture[2] = "DesignWithSilverlight.png";
objPicture[3] = "nibbles.png";
objPicture[4] = "silverlight.png";
objPicture[5] = "silverlightCream.png";
//Array of websites
var objWebsite = new Array();
objWebsite[0] = "http://ADefwebserver.com";
objWebsite[1] = "http://ValeriesWeddings.com";
objWebsite[2] = "http://DesignWithSilverlight.com";
objWebsite[3] = "http://www.nibblestutorials.net";
objWebsite[4] = "http://Silverlight.net";
objWebsite[5] = "http://SilverlightCream.com";
Simply add a picture and a website to the appropriate array to customize the items.
var NumberOfButtons = 5;
var NumberOfButtonsToShow = 4;
You will also need to change the amount of buttons and optionally how many you want to show at one time. The left and right navigation buttons will show up automatically when needed.
if (!window.ToolBarTest)
window.ToolBarTest = {};
ToolBarTest.Page = function()
{
}
// Set the size and number of buttons for the ToolBar
var ButtonSize = 55;
var NumberOfButtons = 5;
var NumberOfButtonsToShow = 4;
//Array of pictures
var objPicture = new Array();
objPicture[0] = "adef.png";
objPicture[1] = "bells.png";
objPicture[2] = "DesignWithSilverlight.png";
objPicture[3] = "nibbles.png";
objPicture[4] = "silverlight.png";
objPicture[5] = "silverlightCream.png";
//Array of websites
var objWebsite = new Array();
objWebsite[0] = "http://ADefwebserver.com";
objWebsite[1] = "http://ValeriesWeddings.com";
objWebsite[2] = "http://DesignWithSilverlight.com";
objWebsite[3] = "http://www.nibblestutorials.net";
objWebsite[4] = "http://Silverlight.net";
objWebsite[5] = "http://SilverlightCream.com";
var ToolBar;
var ToolBarWindow;
var objBox = new Array();
var CurrentLocation = 0;
var scrollPosition = 0;
var LeftButton;
var RightButton;
var storyboard;
var animation;
var ToolBarWidth = NumberOfButtonsToShow * ButtonSize;
ToolBarTest.Page.prototype =
{
handleLoad: function(control, userContext, rootElement)
{
// Get a reference to the various XAML elements
ToolBar = rootElement.findName("ToolBar");
ToolBarWindow = rootElement.findName("ToolBarWindow");
LeftButton = rootElement.findName("LeftButton");
RightButton = rootElement.findName("RightButton");
storyboard = rootElement.findName("Movebar");
animation = rootElement.findName("animateToolbar");
// Add the buttons to the Toolbar
for(i = 0; i <= NumberOfButtons; i++)
{
objBox[i] = new box("box" + i, ToolBar, CurrentLocation, objPicture[i], objWebsite[i]);
CurrentLocation = CurrentLocation + ButtonSize;
}
// Set the Clipping on the ToolBarWindow (Canvas)
// This causes only a portion of the ToolBar (that is also on the ToolBarWindow Canvas) to show
SetToolbarWindowClip(ToolBarWindow, ToolBarWidth);
// Always hide the LeftButton on page load
LeftButton.visibility = "Collapsed";
// Hide the RightButton if it is not needed
if (NumberOfButtons * ButtonSize <= ToolBarWidth)
{
RightButton.visibility = "Collapsed";
}
else
{
// Set the position of the RightButton
RightButton["Canvas.Left"] = ToolBarWidth + (ButtonSize/2);
}
// Attach event handlers to Left and Right buttons
LeftButton.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown));
RightButton.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown));
},
handleMouseDown: function(sender, eventArgs)
{
if(sender.Name == "LeftButton") // LeftButton
{
// Only advance Toolbar (scrollPosition) if it is not already at the the
// first Button
if(scrollPosition != 0)
{
// Move the scrollPosition
scrollPosition+=ButtonSize;
// If the LeftButton is clicked then the RightButton needs to show
RightButton.visibility = "Visible";
// Do not show LeftButton if the first Button is showing
if(scrollPosition == 0)
{
LeftButton.visibility = "Collapsed";
}
else
{
LeftButton.visibility = "Visible";
}
}
}
if(sender.Name == "RightButton") // RightButton
{
// Only advance Toolbar (scrollPosition) if there are Buttons to show
if(scrollPosition >= -((NumberOfButtons * ButtonSize) - ToolBarWidth))
{
// Move the scrollPosition
scrollPosition-=ButtonSize;
// If the RightButtonis clicked then the LeftButton needs to show
LeftButton.visibility = "Visible";
// Do not show RightButton if the last Button is showing
if(scrollPosition == -(((NumberOfButtons + 1) * ButtonSize) - ToolBarWidth))
{
RightButton.visibility = "Collapsed";
}
else
{
RightButton.visibility = "Visible";
}
}
}
// Move the ToolBar by setting it to the current scrollPosition
animation.To = scrollPosition;
storyboard.Begin();
}
}
function SetToolbarWindowClip(objToolBarWindow, dblToolBarWidth)
{
// Since the RectangleGeometry cannot be edited visually in Expression Blend
// It is ok to create it dynamically
var xamlFragment;
// Retrieve a reference to the plug-in.
var plugin = objToolBarWindow.getHost();
// Define a XAML fragment for RectangleGeometry
xamlFragment = '<RectangleGeometry Rect="0,0,xxx,100" />';
// Set the width of the RectangleGeometry to ToolBarWidth
xamlFragment = xamlFragment.replace("xxx", dblToolBarWidth);
// Create the XAML fragment
ToolBarClip = plugin.content.createFromXaml(xamlFragment);
// Set the Clip of the ToolbarWindow (Canvas) to the XAML fragment
objToolBarWindow.Clip = ToolBarClip;
}
// Michael Washington
// Silverlight Tutorials
// http://www.adefwebserver.com/DotNetNukeHELP/Misc/Silverlight/
// Adapted from Justin-Josef Angel's
// "Silverlight Controls - The path to reusable XAML"
// http://blogs.microsoft.co.il/blogs/justinangel/archive/2007/08/14/Silverlight-Controls-_2D00_-The-path-to-reusable-XAML.aspx
// This JavaScript file defines the object "box"
box = function(ID, Parent, XLocation, imgPicture, strWebsite)
{
this._ID = ID + "_";
this._parent = Parent;
this._XLocation = XLocation;
this._imgPicture = imgPicture;
this._strWebsite = strWebsite;
this._host = this._parent.getHost();
this.Element;
// The first step is to retrive the XAML content for the "box"
this.StartXamlDownload();
}
box.prototype =
{
_findNameByXamlID : function(nameInXamlFile)
{
return this._parent.findName(this._getIdFor(nameInXamlFile));
},
_getIdFor : function(nameInXamlFile)
{
return this._ID + nameInXamlFile;
},
StartXamlDownload : function()
{
// A Silverlight "downloader" object is used to retrieve the "box.xaml" file that contains
// the XAML for the "box"
// A delegate is created that will call the "XamlDownloadCompleted" method when the
// download is completed
var xamlDownloader = this._host.createObject("downloader");
xamlDownloader.open("GET", "box.xaml");
xamlDownloader.addEventListener("completed", Silverlight.createDelegate(this, this.XamlDownloadCompleted));
xamlDownloader.send();
},
DownloadPicture : function()
{
// A Silverlight "downloader" object is used to retrieve the Picture
// A delegate is created that will call the "PictureDownloadCompleted" method when the
// download is completed
var xamlDownloader = this._host.createObject("downloader");
xamlDownloader.open("GET", "images/" + this._imgPicture);
xamlDownloader.addEventListener("completed", Silverlight.createDelegate(this, this.PictureDownloadCompleted));
xamlDownloader.send();
},
XamlDownloadCompleted : function(sender, eventArgs)
{
// The download of "box.xaml" has been completed
// "sender.ResponseText" contains the contents of "box.xaml"
var originalXaml = sender.ResponseText;
// In order to avoid name collisions, the name of each "box" object will be replaced
// with a name that begins with the ID that was passed in the object constructor
originalXaml = originalXaml.replace(/Name="/g, "Name=\"" + this._ID);
// The altered "box.xaml" is used to create a XAML object
var plugin = sender.getHost();
var newElement = plugin.content.createFromXaml(originalXaml)
// Set Element to the XAML object so that it can be manipulated
this.Element = newElement;
// The "box" will now be added to the main Canvas
// The XML object is added to the element passed in the constructor
this._parent.children.add(newElement);
// Now that the "box" has been added to the main Canvas
// the "BoxTitle" will be altered and the "box" position will be set
this._setControlReferences();
// Set the picture
// The Downl;oader wil be used because it allows us to know when the image is ready
// If we do not use the Downloader we may try to use an image that is not yet avalaible
this.DownloadPicture();
},
_setControlReferences : function()
{
this._box = this._findNameByXamlID("box");
this._box["Canvas.Left"] = this._XLocation;
this._box["Canvas.Top"] = 10;
this._box.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown));
},
PictureDownloadCompleted : function(sender, eventArgs)
{
// The download of the picture has been completed
// setSource(sender, "") will set the source for the Thumbnail
// to value of "sender" which is the image
var originalXaml = sender.ResponseText;
var Thumbnail = this._findNameByXamlID("Thumbnail");
Thumbnail.setSource(sender, "");
//Also set the Reflection Image
var Thumbnail_Reflection = this._findNameByXamlID("Thumbnail_Reflection");
Thumbnail_Reflection.setSource(sender, "");
},
handleMouseDown: function(sender, eventArgs)
{
// Navigate to the website
window.location.href = this._strWebsite;
}
}
Back To: Silverlight Tutorials
Also See: