<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-7411255283791998153</atom:id><lastBuildDate>Sat, 05 Oct 2024 02:42:30 +0000</lastBuildDate><category>Silverlight</category><category>Deep Zoom</category><category>SimpleViewer</category><category>XamlWriter</category><category>Beta2</category><category>Linq</category><category>RIA Services</category><category>Rx</category><category>Tips</category><category>job</category><title>Project Silverlight</title><description>My adventures into the wonderful world of Silverlight 2+!</description><link>http://projectsilverlight.blogspot.com/</link><managingEditor>noreply@blogger.com (Wilfred Pinto)</managingEditor><generator>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><xhtml:meta content="noindex" name="robots" xmlns:xhtml="http://www.w3.org/1999/xhtml"/><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7411255283791998153.post-7503124713584813767</guid><pubDate>Sat, 18 Oct 2008 22:13:00 +0000</pubDate><atom:updated>2008-10-18T15:25:11.912-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Silverlight</category><category domain="http://www.blogger.com/atom/ns#">SimpleViewer</category><title>SimpleViewer-SL ported to Silverlight 2 and uploaded to CodePlex</title><description>I finally got around to uploading the SimpleViewer-SL source code to &lt;a href="http://www.codeplex.com/simpleviewerSL"&gt;CodePlex&lt;/a&gt;. Minor changes were required to get the code to compile on Silverlight 2.&lt;br /&gt;&lt;br /&gt;The SimpleViewer-SL project on CodePlex can be found here: &lt;a href="http://www.codeplex.com/simpleviewerSL"&gt;http://www.codeplex.com/simpleviewerSL&lt;/a&gt;. Please feel free to report all bugs/issues/enhancements on &lt;a href="http://www.codeplex.com/simpleviewerSL/WorkItem/List.aspx"&gt;this&lt;/a&gt; site.</description><link>http://projectsilverlight.blogspot.com/2008/10/simpleviewer-sl-ported-to-silverlight-2.html</link><author>noreply@blogger.com (Wilfred Pinto)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7411255283791998153.post-516697731428129705</guid><pubDate>Mon, 30 Jun 2008 18:43:00 +0000</pubDate><atom:updated>2008-06-30T11:49:42.462-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Beta2</category><category domain="http://www.blogger.com/atom/ns#">Silverlight</category><category domain="http://www.blogger.com/atom/ns#">SimpleViewer</category><title>SimpleViewer-SL ported to Silverlight 2 Beta 2</title><description>SimpleViewer-SL now works on Beta 2 as well. I updated the inline samples in the previous posts so folks with Beta 2 should be able to view all the sample galleries that I created using SimpleViewer-SL.&lt;br /&gt;&lt;br /&gt;If you recollect from my earlier post, I did not use the ScrollViewer control since I wanted to keep the .xap package as small as possible. This is no longer the case since ScrollViewer is now part of the Silverlight framework itself. I still haven't updated the code to take advantage of this but might do so at a later date.</description><link>http://projectsilverlight.blogspot.com/2008/06/simpleviewer-sl-ported-to-silverlight-2.html</link><author>noreply@blogger.com (Wilfred Pinto)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7411255283791998153.post-9152203555288161848</guid><pubDate>Tue, 13 May 2008 00:29:00 +0000</pubDate><atom:updated>2008-05-12T18:06:55.555-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Silverlight</category><category domain="http://www.blogger.com/atom/ns#">SimpleViewer</category><category domain="http://www.blogger.com/atom/ns#">Tips</category><title>Scrolling, without using ScrollViewer!</title><description>The main objective when building SimpleViewer-SL was to keep the executable as small as possible and hence I didn't have the option of using ScrollViewer. I still needed scrolling functionality though and hence had to take &lt;span style="font-style: italic;"&gt;some&lt;/span&gt; alternate approach. This post is a result of my findings. There is possibly no reason for anyone to take this approach, unless there is a compelling reason to not use ScrollViewer, but it might prove useful!&lt;br /&gt;&lt;br /&gt;So how did I go about implementing scrolling? The trick is to contain the visible area and use TranslateTransform.&lt;br /&gt;&lt;br /&gt;Let's look at the Xaml first&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;UserControl x:Class="SimpleViewer_SL.Thumbnails"&lt;br /&gt; xmlns="http://schemas.microsoft.com/client/2007"&lt;br /&gt; xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;Grid x:Name="LayoutRoot" HorizontalAlignment="Center" VerticalAlignment="Center"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;Grid x:Name="LayoutThumbnailsViewport" HorizontalAlignment="Left"&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;&amp;lt;Grid x:Name="LayoutThumbnails" HorizontalAlignment="Left"&amp;gt;&lt;/span&gt;&lt;br /&gt;  &amp;lt;Grid.RenderTransform&amp;gt;&lt;br /&gt;   &lt;span style="font-weight: bold;"&gt;&amp;lt;TranslateTransform x:Name="GridTranslate" /&amp;gt;&lt;/span&gt;&lt;br /&gt;  &amp;lt;/Grid.RenderTransform&amp;gt;&lt;br /&gt;  &amp;lt;Grid.Resources&amp;gt;&lt;br /&gt;     &lt;span style="font-weight: bold;"&gt;&amp;lt;Storyboard x:Name="GridScrollStoryboard"&amp;gt;&lt;/span&gt;&lt;br /&gt;     &amp;lt;DoubleAnimation x:Name="GridScrollAnimation" Storyboard.TargetName="GridTranslate" Storyboard.TargetProperty="X" Duration="00:00:00.5"/&amp;gt;&lt;br /&gt;     &amp;lt;/Storyboard&amp;gt;&lt;br /&gt;  &amp;lt;/Grid.Resources&amp;gt;&lt;br /&gt; &amp;lt;/Grid&amp;gt;&lt;br /&gt;&amp;lt;/Grid&amp;gt;&lt;br /&gt;&amp;lt;Canvas x:Name="RightNav" Height="25" Width="30" Background="Transparent" HorizontalAlignment="Right"&amp;gt;&lt;br /&gt; &amp;lt;Path Height="25" Width="30" Stretch="Fill"&lt;br /&gt;  Data="F1 M 0,50L 130,50L 80,0L 130,0L 200,70L 130,140L 80,140L 130,90L 0,90L 0,50 Z"&amp;gt;&lt;br /&gt; &amp;lt;/Path&amp;gt;&lt;br /&gt;&amp;lt;/Canvas&amp;gt;&lt;br /&gt;&amp;lt;Canvas x:Name="LeftNav" Height="25" Width="30" Background="Transparent" HorizontalAlignment="Left"&amp;gt;&lt;br /&gt; &amp;lt;Path Height="25" Width="30" Stretch="Fill"&lt;br /&gt;  Data="F1 M 200,90L 70,90L 120,140L 70,140L 0,70L 70,0L 120,0L 70,50L 200,50L 200,90 Z"&amp;gt;&lt;br /&gt; &amp;lt;/Path&amp;gt;&lt;br /&gt;&amp;lt;/Canvas&amp;gt;&lt;br /&gt;&amp;lt;/Grid&amp;gt;&lt;br /&gt;&amp;lt;/UserControl&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What we are trying to do here is display the thumbnails in a grid, but, as you can see from the above Xaml, I have had to create 3 grids to implement scrolling.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;LayoutThumbnails - This is the grid which will host the thumbnails&lt;/li&gt;&lt;li&gt;LayoutThumbnailsViewport - This is the grid which will host the translated thumbnails&lt;/li&gt;&lt;li&gt;LayoutRoot - This is the grid which will host the clipped thumbnails&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;GridTranslate - This exposes the translate transform of LayoutThumbnails&lt;/li&gt;&lt;li&gt;GridScrollStoryboard - This is the storyboard that animates GridTranslate to simulate (horizontal) scrolling&lt;/li&gt;&lt;/ul&gt;Now for some code&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Thumbnails : UserControl&lt;br /&gt;{&lt;br /&gt; Page _parent = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _borderWidth = 2;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _selectedThumbnailIndex = -1;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _rowCount = 0;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _colCount = 0;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _totalColCount = 0;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _numPages = 0;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _currPage = 0;&lt;br /&gt; Size _thumbSize = &lt;span class="kwrd"&gt;new&lt;/span&gt; Size { Width = 65, Height = 65 };&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; _borderPlusPaddingWidth = 0;&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; ControlWidth { get { &lt;span class="kwrd"&gt;return&lt;/span&gt; (_thumbSize.Width + (_borderPlusPaddingWidth * 2)) * _colCount; }}&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; Thumbnails(Page parent)&lt;br /&gt; {&lt;br /&gt;     _parent = parent;&lt;br /&gt;     _rowCount = _parent.Settings.ThumbnailRows;&lt;br /&gt;     _colCount = _parent.Settings.ThumbnailColumns;&lt;br /&gt;     _totalColCount = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)(Math.Ceiling((&lt;span class="kwrd"&gt;double&lt;/span&gt;)_parent.Settings.ImagesSettings.Count / _rowCount));&lt;br /&gt;     _numPages = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)(Math.Ceiling((&lt;span class="kwrd"&gt;double&lt;/span&gt;)_totalColCount / _colCount));&lt;br /&gt;     _borderPlusPaddingWidth = _parent.Settings.ThumbPadding + _borderWidth;&lt;br /&gt;&lt;br /&gt;     InitializeComponent();&lt;br /&gt;  &lt;br /&gt;     &lt;span class="asp"&gt;LayoutRoot.Width = ControlWidth; // ****1****&lt;/span&gt;&lt;br /&gt;     &lt;span class="asp"&gt;LayoutThumbnailsViewport.Width = ControlWidth * _numPages; // ****2****&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;     CreateLayout();&lt;br /&gt;     DrawThumbnails();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; CreateLayout() {&lt;br /&gt;     &lt;span class="rem"&gt;// Thumbnails &lt;/span&gt;&lt;br /&gt;     LayoutRoot.RowDefinitions.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; RowDefinition());&lt;br /&gt;     LayoutThumbnailsViewport.SetValue(Grid.RowProperty, 0);&lt;br /&gt;  &lt;br /&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; (_numPages &amp;gt; 0) {&lt;br /&gt;         &lt;span class="rem"&gt;// Navigation Arrows&lt;/span&gt;&lt;br /&gt;         LayoutRoot.RowDefinitions.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; RowDefinition { Height = &lt;span class="kwrd"&gt;new&lt;/span&gt; GridLength(30) });&lt;br /&gt;         RightNav.SetValue(Grid.RowProperty, 1);&lt;br /&gt;         LeftNav.SetValue(Grid.RowProperty, 1);&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DrawThumbnails()&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; row = 0; row &amp;lt; _rowCount; row++) {&lt;br /&gt;         LayoutThumbnails.RowDefinitions.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; RowDefinition { Height = &lt;span class="kwrd"&gt;new&lt;/span&gt; GridLength(_thumbSize.Height + (_borderPlusPaddingWidth * 2)) });&lt;br /&gt;     }&lt;br /&gt;  &lt;br /&gt;     &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; col = 0; col &amp;lt; _colCount * _numPages; col++) {&lt;br /&gt;         LayoutThumbnails.ColumnDefinitions.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; ColumnDefinition { Width = &lt;span class="kwrd"&gt;new&lt;/span&gt; GridLength(_thumbSize.Width + (_borderPlusPaddingWidth * 2)) });&lt;br /&gt;     }&lt;br /&gt;  &lt;br /&gt;     &lt;span class="kwrd"&gt;int&lt;/span&gt; imageIndex = 0;&lt;br /&gt;     &lt;span class="kwrd"&gt;int&lt;/span&gt; startCol = 0;&lt;br /&gt;     &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; page = 0; page &amp;lt; _numPages; page++) {&lt;br /&gt;         &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; row = 0; row &amp;lt; _rowCount; row++) {&lt;br /&gt;             &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; col = 0; col &amp;lt; _colCount &amp;amp;&amp;amp; imageIndex &amp;lt; _parent.Settings.ImagesSettings.Count; col++) {&lt;br /&gt;                 CreateImage(row, col + startCol, imageIndex);&lt;br /&gt;                 imageIndex++;&lt;br /&gt;             }&lt;br /&gt;         }&lt;br /&gt;         startCol += _colCount;&lt;br /&gt;     }&lt;br /&gt;  &lt;br /&gt;     LeftNav.MouseLeftButtonUp += (sender, e) =&amp;gt; {&lt;br /&gt;         ScrollLeft();&lt;br /&gt;     };&lt;br /&gt;  &lt;br /&gt;     RightNav.MouseLeftButtonUp += (sender, e) =&amp;gt; {&lt;br /&gt;         ScrollRight();&lt;br /&gt;     };&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CreateImage(&lt;span class="kwrd"&gt;int&lt;/span&gt; row, &lt;span class="kwrd"&gt;int&lt;/span&gt; col, &lt;span class="kwrd"&gt;int&lt;/span&gt; imageIndex)&lt;br /&gt; {&lt;br /&gt;     Image thumb = &lt;span class="kwrd"&gt;new&lt;/span&gt; Image();&lt;br /&gt;     thumb.Source = &lt;span class="kwrd"&gt;new&lt;/span&gt; BitmapImage(&lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(_parent.Settings.ThumbPath + _parent.Settings.ImagesSettings[imageIndex].Name, UriKind.Relative));&lt;br /&gt;&lt;br /&gt;     Border border = &lt;span class="kwrd"&gt;new&lt;/span&gt; Border {&lt;br /&gt;                         Width = _thumbSize.Width + (_borderWidth*2),&lt;br /&gt;                         Height = _thumbSize.Height + (_borderWidth*2),&lt;br /&gt;                         BorderThickness = &lt;span class="kwrd"&gt;new&lt;/span&gt; Thickness(_borderWidth),&lt;br /&gt;                         BorderBrush = &lt;span class="kwrd"&gt;new&lt;/span&gt; SolidColorBrush(_parent.Settings.FrameColor),&lt;br /&gt;                         Margin = &lt;span class="kwrd"&gt;new&lt;/span&gt; Thickness(_parent.Settings.ThumbPadding),&lt;br /&gt;                         Opacity = 0.6&lt;br /&gt;                                 };&lt;br /&gt;     border.SetValue(Grid.RowProperty, row);&lt;br /&gt;     border.SetValue(Grid.ColumnProperty, col);&lt;br /&gt;     border.SetValue(NameProperty, &lt;span class="str"&gt;"Image"&lt;/span&gt; + imageIndex.ToString());&lt;br /&gt;     border.Tag = imageIndex.ToString();            &lt;span class="rem"&gt;// Tag can only handle Strings as of SL2 B1 release&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;     border.Child = thumb;&lt;br /&gt;     LayoutThumbnails.Children.Add(border);&lt;br /&gt;  &lt;br /&gt;     border.MouseLeftButtonUp += (sender, e) =&amp;gt; {&lt;br /&gt;         Rect LayoutRootRect = &lt;span class="kwrd"&gt;new&lt;/span&gt; Rect(0, 0, LayoutRoot.RenderSize.Width, LayoutRoot.RenderSize.Height);&lt;br /&gt;         &lt;span class="asp"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (LayoutRootRect.Contains(e.GetPosition(LayoutRoot))) { // ****3****&lt;/span&gt;&lt;br /&gt;             Border currentBorder = (Border)sender;&lt;br /&gt;             SelectedThumbnailIndex = Int32.Parse((&lt;span class="kwrd"&gt;string&lt;/span&gt;)currentBorder.Tag);&lt;br /&gt;         }&lt;br /&gt;     };&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CanScrollRight    { get { &lt;span class="kwrd"&gt;return&lt;/span&gt; ((_currPage + 1) &amp;lt; _numPages); }}&lt;br /&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; CanScrollLeft    { get { &lt;span class="kwrd"&gt;return&lt;/span&gt; (_currPage &amp;gt; 0); }}&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ScrollRight()&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; (CanScrollRight) {&lt;br /&gt;         _currPage++;&lt;br /&gt;         GridScrollAnimation.To = -(_thumbSize.Width + (_borderPlusPaddingWidth * 2)) * _colCount * _currPage;&lt;br /&gt;         GridScrollStoryboard.Begin();&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ScrollLeft()&lt;br /&gt; {&lt;br /&gt;     &lt;span class="kwrd"&gt;if&lt;/span&gt; (CanScrollLeft) {&lt;br /&gt;         _currPage--;&lt;br /&gt;         GridScrollAnimation.To = -(_thumbSize.Width + (_borderPlusPaddingWidth * 2)) * _colCount * _currPage;&lt;br /&gt;         GridScrollStoryboard.Begin();&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Most of the code is self explanatory but I would like to elaborate on a few key points which is highlighted in the code:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The width of LayoutThumbnailsViewport should be equal to or greater than the width of the entire grid. If the width is not explicitly set or is less than the width of the entire grid, translatetransform will clip the contents that lie outside the area of the grid&lt;/li&gt;&lt;li&gt;The width of LayoutRoot should be set to the viewing area. This should be less than the width of LayoutThumbnailsViewport if scrolling is desired&lt;/li&gt;&lt;li&gt;One undesired effect of creating this layout is that the underlying grid (LayoutThumbnails) and hence the thumbnails receive mouse events even for the contents that is outside the visible area (LayoutRoot). To circumvent this I had to put this check - if (LayoutRootRect.Contains(e.GetPosition(LayoutRoot))) - in the border.MouseLeftButtonUp event handler. &lt;span style="font-style:italic;"&gt;(Note that border is synonymous with thumbnail)&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;iframe src="http://thepintospatronus.com/simpleviewer-sl/gallery2/gallery1.html" height="200" width="260"&gt;&lt;/iframe&gt;</description><link>http://projectsilverlight.blogspot.com/2008/05/scrolling-without-using-scrollviewer.html</link><author>noreply@blogger.com (Wilfred Pinto)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7411255283791998153.post-3516544117505498601</guid><pubDate>Mon, 05 May 2008 04:45:00 +0000</pubDate><atom:updated>2008-05-08T17:38:36.753-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Silverlight</category><category domain="http://www.blogger.com/atom/ns#">SimpleViewer</category><title>SimpleViewer-SL Beta 1</title><description>&lt;span style="font-style: italic;"&gt;Update 5/8/08: Fixed blank screen bug when navigating between thumbnails, and improved browser resizing support...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Silverlight version of the flash based photo album viewer - &lt;a href="http://www.airtightinteractive.com/simpleviewer/"&gt;SimpleViewer&lt;/a&gt;, is here! I decided to call it &lt;span style="font-weight: bold;"&gt;SimpleViewer-SL&lt;/span&gt; for now.&lt;br /&gt;&lt;br /&gt;Here are a few examples that were created using SimpleViewer-SL &lt;span style="font-style: italic;"&gt;(the keyboard arrow keys are supported as well)&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://thepintospatronus.com/simpleviewer-sl/gallery1/gallery1.html" target="_blank"&gt;Thumbnails on the left, 3x3 grid&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://thepintospatronus.com/simpleviewer-sl/gallery1/gallery2.html" target="_blank"&gt;Thumbnails on the right, 5x4 grid&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://thepintospatronus.com/simpleviewer-sl/gallery1/gallery3.html" target="_blank"&gt;Thumbnails on bottom, 2x4 grid&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://thepintospatronus.com/simpleviewer-sl/gallery1/gallery4.html" target="_blank"&gt;Thumbnails on the left, with background image&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;SimpleViewer-SL is highly customizable. It is compatible with SimpleViewer and hence all options exposed by SimpleViewer are applicable to SimpleViewer-SL as well. The options are listed &lt;a href="http://www.airtightinteractive.com/simpleviewer/options.html"&gt;here&lt;/a&gt;. The only XML option that is not supported at this time is enableRightClickOpen. &lt;span style="font-style: italic;"&gt;Note that the text fields like title and Caption should be plain text (no HTML) for now since I haven't implemented the HTML text control as yet.&lt;/span&gt; As for the HTML options, the only supported option is xmlDataPath. The HTML option should be passed to the SimpleViewer-SL Silverlight object using the param tag - &lt;span style="font-style: italic;"&gt;&amp;lt;param name="initParams" value="xmlDataPath=gallery1.xml" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The album can be created using any of the methods described &lt;a href="http://www.airtightinteractive.com/simpleviewer/auto_desktop_instruct.html"&gt;here&lt;/a&gt; . After creating the albums, a few modifications to the generated file(s) is required to make it work on SimpleViewer-SL.&lt;br /&gt;&lt;br /&gt;The xap can be found &lt;a href="http://thepintospatronus.com/simpleviewer-sl/gallery1/SimpleViewer-SL.xap"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The directory structure for the samples is as follows:&lt;pre&gt;&lt;br /&gt; gallery1/&lt;br /&gt;   SimpleViewer-SL.xap&lt;br /&gt;   gallery1.html&lt;br /&gt;   gallery1.xml&lt;br /&gt;   gallery2.html&lt;br /&gt;   gallery2.xml&lt;br /&gt;   gallery3.html&lt;br /&gt;   gallery3.xml&lt;br /&gt;   gallery4.html&lt;br /&gt;   gallery4.xml&lt;br /&gt;   thumbs/&lt;br /&gt;     65x65 thumbnail images&lt;br /&gt;   images/&lt;br /&gt;     the corresponding big images&lt;/pre&gt;&lt;br /&gt;Between the above links, the sample html and xml files, it should be fairly straightforward for anyone to figure out how to use SimpleViewer-SL. Overall it is fairly feature complete but there is always room for improvement. &lt;s&gt;It is a little unstable, in that sometime navigating between thumbnails results in a blank screen, but I think it is more to do with Silverlight being a Beta release&lt;/s&gt; &lt;span style="font-style: italic;"&gt;(looks like it was more to do with my code!)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This exercise took me a little over a week of part time work so I have to say that I am pretty impressed with Silverlight. Most of my time was spent in figuring out a way to work around Silverlight 2 Beta 1 bugs. I suspect that I can simplify the code a bit after the final release of Siverlight 2. Nevertheless, the current size of SimpleViewer-SL is a mere 17kb, the same as SimpleViewer, with lots of opportunity for improvement.&lt;br /&gt;&lt;br /&gt;For those looking for the code, I am planning to codeplex it when I get some time. Feel free to leave comments to pressure me into doing it sooner rather than later!</description><link>http://projectsilverlight.blogspot.com/2008/05/simpleviewer-sl-beta-1.html</link><author>noreply@blogger.com (Wilfred Pinto)</author><thr:total>7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-7411255283791998153.post-5646375427464037190</guid><pubDate>Fri, 25 Apr 2008 18:09:00 +0000</pubDate><atom:updated>2008-04-25T11:41:47.066-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Silverlight</category><category domain="http://www.blogger.com/atom/ns#">SimpleViewer</category><title>Next Project - Port SimpleViewer to Silverlight</title><description>Having run out of ideas on how further to exploit Deep Zoom, I am going to now focus my energy on porting the closed-source flash based &lt;a href="http://www.airtightinteractive.com/simpleviewer/"&gt;SimpleViewer&lt;/a&gt; to Silverlight. Again, my objective is to learn Silverlight, so I will try to push some boundaries (&lt;span style="font-style:italic;"&gt;if required&lt;/span&gt;). As part of this exercise, I will try to stick to the original goal of SimpleViewer, that is keep the download as small as possible. The current version (1.8.5) of SimpleViewer is only 17k and that is what I am aiming for. This, of course, means no using the extended controls, but only what is available in the core Silverlight 2 SDK!&lt;br /&gt;&lt;br /&gt;So, why SimpleViewer? I actually use it in my personal blog and have always wanted more control over it. I also want to know what it takes to create the same experience in Silverlight. I am expecting this to be a trivial exercise, but let's see!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;My first roadblock!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I wanted to keep everything as dynamic as possible. This means no explicitly specifying the height and width of any control. I was happy to see that the image control provides this capability and is able to work well within the constraints of MaxWidth and MaxHeight. This was all wonderful and perfect for my needs but now I wanted to draw a simple border around the image. Pretty easy...all I need is the dimensions of the image (control), but this is where it got a little complicated. The image control does give access to the dimensions but a little too late. I won't go into the details here but I did post it on the &lt;a href="http://silverlight.net/forums/t/14855.aspx"&gt;Silverlight.net&lt;/a&gt; forum is anyone's interested. By the way this is a great forum and one of the best places to get answers to all your Silverlight questions or issues.&lt;br /&gt;&lt;br /&gt;What I discovered is that the image loaded event is not a reliable place to extract the dimensions from the image control. I tried a kludgey workaround by creating a timer and accessing the dimensions from the image control a little later - around 100 milli seconds - but this is definitely not reliable. But at least I had a solution!&lt;br /&gt;&lt;br /&gt;While I was playing with it some more, I discovered the SizeChanged event. This also doesn't help if the image dimensions are extracted from the image control itself, but I discovered that the event itself has the size, and that is when I had my solution! &lt;br /&gt;&lt;br /&gt;There might be some issues with this so please leave a comment if you find something. I am assuming this is a bug with the image loaded event so, hopefully, it will be fixed in the next release of Silverlight. &lt;span style="font-style:italic;"&gt;But, for now, it looks like I can make some "not so kludgey" progress!&lt;/span&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;MyImage.SizeChanged += (sender, e) =&amp;gt; {&lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.PreviousSize.Width == 0 &amp;amp;&amp;amp; e.PreviousSize.Height == 0 &amp;amp;&amp;amp; e.NewSize != e.PreviousSize) {&lt;br /&gt;        &lt;span class="rem"&gt;// e.NewSize contains the dimension of the image&lt;/span&gt;&lt;br /&gt;        &lt;span class="rem"&gt;// MyImage.Width and MyImage.ActualWidth is unreliable so use e.NewSize instead&lt;/span&gt;&lt;br /&gt;        DrawBorderAroundImage(e.NewSize);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;</description><link>http://projectsilverlight.blogspot.com/2008/04/next-project-port-simpleviewer-to.html</link><author>noreply@blogger.com (Wilfred Pinto)</author><thr:total>4</thr:total></item></channel></rss>