Personal, Poems

Vihan’s Dream

Tonight I woke up In my son’s dream
My nose was running, but I felt clean

Roof of sky and hugs of kin
Bears to play and dolphins to swim

Eyes were bright, no clouds of grim
Future was flowing in bubbly stream

Faces were full of smiles and grin
Locked were steps and up was chin

Had heart of gold, no strains of mean
No hurry to win and no rush to sin

Everything was perfect, everything was sane
There was yang in balance with yin

Standard
Professional, Software

All Search Application Posts So Far…

Wanted to consolidate all search application posts so far

Technorati Tags: ,

https://vivekdalvi.wordpress.com/2008/03/28/part-1-live-search-using-silverlight-main-page/

https://vivekdalvi.wordpress.com/2008/03/29/part-2-live-search-using-silverlight-live-search-call-and-progress/

https://vivekdalvi.wordpress.com/2008/03/30/part-3-image-search-result-view/

https://vivekdalvi.wordpress.com/2008/04/06/part-4-image-detail-view/

https://vivekdalvi.wordpress.com/2008/04/15/part-5-better-image-detail-view/

https://vivekdalvi.wordpress.com/2008/04/21/part-6-slider-for-tile-size/

https://vivekdalvi.wordpress.com/2008/04/22/part-7-web-search-results/

https://vivekdalvi.wordpress.com/2008/04/24/part-8-3d-image-view-using-custom-layout/

https://vivekdalvi.wordpress.com/2008/04/25/part-9-image-size-filter/

Standard
Professional, Software

Part 9: Image Size Filter

This part adds a filtering images out of view using size as the basis. So If user wants to see images bigger than certain size, he could use the slider to do it. This means I needed to convert size into opacity so if the size of image was less than what was set in the slider then I needed to set the opacity of the image. Here is how it looks like when it is running

imagesizefilter

To get to this point, I need to build an IValueConverter implementation that converts size into opacity, which was pretty straight forward.

SizeToOpacityConverter.cs

   1: using System;
   2: using System.Windows.Data;
   3: 
   4: namespace Search
   5: {
   6:     public class SizeToOpacityConverter : IValueConverter
   7:     {
   8:         #region Public Members
   9: 
  10:         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  11:         {
  12:             Tile tile = (Tile)parameter;
  13:             int imagesize = (int)value/1000;
  14:             if (tile.FilterSize < imagesize)
  15:                 return 1;
  16:             else
  17:                 return 0.2;
  18:         }
  19: 
  20:         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  21:         {
  22:             return null;
  23:         }
  24:         #endregion
  25:     }
  26: }

ImageGridView.Xaml

   1: <UserControl x:Class="Search.Image3DView"
   2:     xmlns="http://schemas.microsoft.com/client/2007"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:local="clr-namespace:Search;assembly=Search"
   5:     xmlns:control="clr-namespace:MyControls;assembly=MyControls"
   6:     >
   7:     <UserControl.Resources>
   8:         <local:ImageSourceConverter x:Key="imagesourceconverter"/>
   9:
  10:         <local:Tile x:Key="TileInfo"/>
  11:     </UserControl.Resources>
  12:     <ItemsControl ItemsSource="{Binding}">
  13:         <ItemsControl.ItemsPanel>
  14:             <ItemsPanelTemplate>
  15:                 <control:Stack3DPanel FrameCount="5"
  16:                                       MouseLeftButtonDown="Stack3DPanel_MouseLeftButtonDown"/>
  17:             </ItemsPanelTemplate>
  18:         </ItemsControl.ItemsPanel>
  19:         <ItemsControl.ItemTemplate>
  20:             <DataTemplate>
  21:                 <Border
  22:                     BorderThickness="2,2,2,2" BorderBrush="#FF313131"
  23:                     CornerRadius="5,5,5,5"
  24:                     MouseEnter="Border_MouseEnter"
  25:                     MouseLeave="Border_MouseLeave" Background="White">
  26:                     <Border.RenderTransform>
  27:                         <TransformGroup>
  28:                             <ScaleTransform ScaleX="1" ScaleY="1"/>
  29:                             <SkewTransform AngleX="0" AngleY="0"/>
  30:                             <RotateTransform Angle="0"/>
  31:                             <TranslateTransform X="0" Y="0"/>
  32:                         </TransformGroup>
  33:                     </Border.RenderTransform>
  34:                     <Image
  35:                         Margin="5,5,5,5"  Stretch="Uniform"
  36:                         Source="{Binding Image.ImageURL , Converter={StaticResource imagesourceconverter}}"
  37:                         RenderTransformOrigin="0.5,0.5"
  38:                         x:Name="image"
  39:                         HorizontalAlignment="Stretch">
  40:                         <Image.RenderTransform>
  41:                             <TransformGroup>
  42:                                 <ScaleTransform/>
  43:                                 <SkewTransform/>
  44:                                 <RotateTransform/>
  45:                                 <TranslateTransform/>
  46:                             </TransformGroup>
  47:                         </Image.RenderTransform>
  48:                     </Image>
  49:                 </Border>
  50:             </DataTemplate>
  51:         </ItemsControl.ItemTemplate>
  52:     </ItemsControl>
  53: </UserControl>

Second part was the bind the opacity of images with filesize and use above SizeToOpeacityConverter. Interesting part of this xaml is

<Image
   Source="{Binding Image.ThumbnailURL, Converter={StaticResource imagesourceconverter}}"
   Opacity="{Binding Image.ImageFileSize ,
Converter={StaticResource sizetoopacityconverter},
ConverterParameter={StaticResource TileInfo}}"
   ImageFailed="Image_ImageFailed"
   Cursor="Hand"
   Margin="1,1,1,1"/>

Then I hit this problem, which I ended up solving but I am not sure if this is the best way to solve it. If I find it, i will post again later. The problem is that thing that updates in above code is ConverterParameter for the Binding and When parameter changes, I could figure out a way to update a single binding. So I ended up writing this code which actually performance wise was good enough for me but that just seems like a wrong way to do it..

Page.xaml.cs

private voidsizeslider_ValueChanged(objectsender, RoutedPropertyChangedEventArgs<double> e)
{
    strings = e.NewValue.ToString();
    txtvalue.Text = “> ” + s.Split(new char[]{‘.’})[0] + ” (KB)”;
    imageGrid.FilterSize = e.NewValue;
    imageGrid.DataContext = null;
    imageGrid.DataContext = _searchresultcollectioncollection;
}

This basically resets the datacontext and hence all bindings are recomputed.

Here is the copy of working project.

Standard
Professional, Software

Part 8: 3D Image View Using Custom Layout

3D Image View

I think to make view usable, it needs lot more work. But I wanted to build something that could not be easily built using HTML ( and I needed a place to use my stack 3d panel 🙂 ). But here is what it looks like. Getting to this place was pretty easy because I already had a panel that could do this.

 image3dview

Here are few things I used in this…

  1. Custom Panels: Building Custom Layout
  2. ItemsControl: Changing default layout

Building this involved building a user control which has a itemscontrol but instead of using default stackpanel that lays out items vertically, I used stack3dpanel to layout items as if they are in 3d.

Image3DView.xaml

   1: <UserControl x:Class="Search.Image3DView"
   2:     xmlns="http://schemas.microsoft.com/client/2007"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:local="clr-namespace:Search;assembly=Search"
   5:     xmlns:control="clr-namespace:MyControls;assembly=MyControls"
   6:     >
   7:     <UserControl.Resources>
   8:         <local:ImageSourceConverter x:Key="imagesourceconverter"/>
   9:
  10:         <local:Tile x:Key="TileInfo"/>
  11:     </UserControl.Resources>
  12:     <ItemsControl ItemsSource="{Binding}">
  13:         <ItemsControl.ItemsPanel>
  14:             <ItemsPanelTemplate>
  15:                 <control:Stack3DPanel FrameCount="5"
  16:                                       MouseLeftButtonDown="Stack3DPanel_MouseLeftButtonDown"/>
  17:             </ItemsPanelTemplate>
  18:         </ItemsControl.ItemsPanel>
  19:         <ItemsControl.ItemTemplate>
  20:             <DataTemplate>
  21:                 <Border
  22:                     BorderThickness="2,2,2,2" BorderBrush="#FF313131"
  23:                     CornerRadius="5,5,5,5"
  24:                     MouseEnter="Border_MouseEnter"
  25:                     MouseLeave="Border_MouseLeave" Background="White">
  26:                     <Border.RenderTransform>
  27:                         <TransformGroup>
  28:                             <ScaleTransform ScaleX="1" ScaleY="1"/>
  29:                             <SkewTransform AngleX="0" AngleY="0"/>
  30:                             <RotateTransform Angle="0"/>
  31:                             <TranslateTransform X="0" Y="0"/>
  32:                         </TransformGroup>
  33:                     </Border.RenderTransform>
  34:                     <Image
  35:                         Margin="5,5,5,5"  Stretch="Uniform"
  36:                         Source="{Binding Image.ImageURL , Converter={StaticResource imagesourceconverter}}"
  37:                         RenderTransformOrigin="0.5,0.5"
  38:                         x:Name="image"
  39:                         HorizontalAlignment="Stretch">
  40:                         <Image.RenderTransform>
  41:                             <TransformGroup>
  42:                                 <ScaleTransform/>
  43:                                 <SkewTransform/>
  44:                                 <RotateTransform/>
  45:                                 <TranslateTransform/>
  46:                             </TransformGroup>
  47:                         </Image.RenderTransform>
  48:                     </Image>
  49:                 </Border>
  50:             </DataTemplate>
  51:         </ItemsControl.ItemTemplate>
  52:     </ItemsControl>
  53: </UserControl>

The most interesting part of this xaml is

   1: <ItemsControl ItemsSource="{Binding}">
   2:     <ItemsControl.ItemsPanel>
   3:         <ItemsPanelTemplate>
   4:             <control:Stack3DPanel FrameCount="5"
   5:                                   MouseLeftButtonDown="Stack3DPanel_MouseLeftButtonDown"/>
   6:         </ItemsPanelTemplate>
   7:     </ItemsControl.ItemsPanel>

This tells ItemsControl to use my custom panel to layout individual items in the source collection. This control also uses valueconverters for converting URI to source.

Image3DView.xaml.cs

   1: using System;
   2: using System.Windows;
   3: using System.Windows.Input;
   4: using System.Windows.Controls;
   5: using System.Windows.Media;
   6: using System.Windows.Media.Imaging;
   7: using MyControls;
   8: 
   9: namespace Search
  10: {
  11:     public partial class Image3DView : UserControl
  12:     {
  13:         public Image3DView()
  14:         {
  15:             InitializeComponent();
  16:         }
  17: 
  18:         //if iamge fails to load then placeholder image is shown
  19:         private void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
  20:         {
  21:             ((Image)sender).Source = new BitmapImage(new Uri("notfound.jpg", UriKind.Relative));
  22:         }
  23: 
  24:         //on mouse enter, increase the size of image and set opacity to 1
  25:         private void Border_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
  26:         {
  27:             //hover effect
  28:             Border b = (Border)sender;
  29:             b.Child.Opacity = 1;
  30:             TransformGroup tg = b.RenderTransform as TransformGroup;
  31:             ScaleTransform st = tg.Children[0] as ScaleTransform;
  32:             st.ScaleX = 1.0;
  33:             st.ScaleY = 1.05;
  34:             b.Background = new SolidColorBrush(Colors.LightGray);
  35:         }
  36: 
  37:         //on mouse leave, reset the size of image and set opacity to 0
  38:         private void Border_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
  39:         {
  40:             //reset hover effect
  41:             Border b = (Border)sender;
  42:             b.Child.Opacity = 0.8;
  43:             TransformGroup tg = b.RenderTransform as TransformGroup;
  44:             ScaleTransform st = tg.Children[0] as ScaleTransform;
  45:             st.ScaleX = 1;
  46:             st.ScaleY = 1;
  47:             b.Background = new SolidColorBrush(Colors.White);
  48:         }
  49: 
  50:         private void Stack3DPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  51:         {
  52:             if (e.Handled == false)
  53:             {
  54:                 ((Stack3DPanel)sender).MoveNext();
  55:             }
  56:         }
  57:     }
  58: }

I also made some changes to Page.xaml and Page.xaml.cs to show this view appropriately. Here is the copy of full working project.

Standard
Professional, Software

Part 7: Web Search Results

Technorati Tags: ,,

Adding this was more of a question of restructuring my code than really using any new functionality. Everything needed was already built to get to Image Search working.

Few things I had to added to get to this view were…

  1. I changed networking request code so that I make a 1 request per category. I show the first category whenever it is ready and keep on requesting other categories.
  2. Created a user control to show the web results. which is pretty straightforward as it is a items control where items are stacked vertically (which is default).
  3. Added radio button to toggle the visibility of default types of search results
  4. I also added code so that user can type in search text and hit “Enter” to start searching.

websearch

Here is the copy of working project.

Standard
Professional, Software

Part 6: Slider for Tile Size

Technorati Tags: ,,

I wanted to add a slider to control a size of the tile. So that user can increase the height/width of the tiles of pictures as shown below.

default large small

This was a pretty trivial task since I had used databinding to define the size of each tile. Here are things that were interesting

  1. INotifyPropertyChanged
  2. Static Resources
  3. Source databinding
  4. Slider

Here is how the size of the each tile was controlled…

Created a class that represents the size of tile

   1: using System;
   2: using System.Windows;
   3: using System.ComponentModel;
   4: 
   5: namespace Search
   6: {
   7:     /// <summary>
   8:     /// Class that holds the tile settings. It implements INotifyPropertyChanged
   9:     /// so that it can be used as a source of databinding
  10:     /// </summary>
  11:     public class Tile : INotifyPropertyChanged
  12:     {
  13: 
  14:         #region Public Members
  15:         //implements INotifyPropertyChanged event
  16:         public event PropertyChangedEventHandler PropertyChanged;
  17: 
  18:         //represents the height of a tile
  19:         public double TileHeight
  20:         {
  21:             get { return _tileheight; }
  22:             set
  23:             {
  24:                 _tileheight = value;
  25:                 NotifyPropertyChanged("TileHeight");
  26:             }
  27:         }
  28: 
  29:         //represents width of a tile
  30:         public double TileWidth
  31:         {
  32:             get { return _tilewidth; }
  33:             set
  34:             {
  35:                 _tilewidth = value;
  36:                 NotifyPropertyChanged("TileWidth");
  37:             }
  38:         }
  39: 
  40:         //represents padding around a tile
  41:         public Thickness TilePadding
  42:         {
  43:             get { return _tilepadding; }
  44:             set
  45:             {
  46:                 _tilepadding = value;
  47:                 NotifyPropertyChanged("TilePadding");
  48:             }
  49:         }
  50:         #endregion
  51: 
  52:         #region Private Memebers
  53: 
  54:         private double _tileheight = 10;
  55:         private double _tilewidth = 10;
  56:         private Thickness _tilepadding = new Thickness(5);
  57: 
  58:         //fires Property Change event. 
  59:         private void NotifyPropertyChanged(String info)
  60:         {
  61:             if (PropertyChanged != null)
  62:             {
  63:                 PropertyChanged(this, new PropertyChangedEventArgs(info));
  64:             }
  65:         }
  66:         #endregion
  67:     }
  68: }
  69: 

This class had implemented INotifyPropertyChanged so that it can serve as a data source in two-way binding.

Created a static resource to instantiate the class

This was done so that I can databind to the instance of the class in my markup using Source syntax.

   1: <UserControl x:Class="Search.ImageGridView"
   2:         xmlns="http://schemas.microsoft.com/client/2007"
   3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:         xmlns:control="clr-namespace:Search;assembly=Search"
   5:         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   6:         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   7:         mc:Ignorable="d" d:DesignWidth="295" d:DesignHeight="234" >
   8:     <UserControl.Resources>
   9:         <control:ImageSourceConverter x:Key="imagesourceconverter"/>
  10:         <control:Tile x:Key="TileInfo"/>
  11:     </UserControl.Resources>

Databind size of image to instance of tile class using source

Since my controls data context was the result returned by live service APIs, I needed to use source syntax to control the property of the tile.

   1: <DataTemplate>
   2:         <Border
   3:             BorderThickness="2,2,2,2" BorderBrush="#FF313131"
   4:             CornerRadius="5,5,5,5"
   5:             Height="{Binding TileHeight, Source={StaticResource TileInfo}}" 
   6:             Width="{Binding TileWidth, Source={StaticResource TileInfo}}"
   7:      Margin="{Binding TilePadding, Source={StaticResource TileInfo}}" 
   8:             MouseEnter="Border_MouseEnter"
   9:             MouseLeave="Border_MouseLeave"
  10:             RenderTransformOrigin="1,1"
  11:             MouseLeftButtonDown="Border_MouseLeftButtonDown"
  12:             MouseLeftButtonUp="Border_MouseLeftButtonUp">
  13:             <Border.RenderTransform>
  14:                 <TransformGroup>
  15:                     <ScaleTransform ScaleX="1" ScaleY="1"/>
  16:                     <SkewTransform AngleX="0" AngleY="0"/>
  17:                     <RotateTransform Angle="0"/>
  18:                     <TranslateTransform X="0" Y="0"/>
  19:                 </TransformGroup>
  20:             </Border.RenderTransform>
  21:             <Border.Background>
  22:                 <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  23:                     <GradientStop Color="#FFFFFFFF"/>
  24:                     <GradientStop Color="#FF71A7BB" Offset="1"/>
  25:                 </LinearGradientBrush>
  26:             </Border.Background>
  27:                 <Image
  28:                 Source="{Binding Image.ThumbnailURL, Converter={StaticResource imagesourceconverter}}"
  29:                 ImageFailed="Image_ImageFailed"
  30:                 Cursor="Hand" Opacity="0.7"
  31:                 Margin="1,1,1,1"/>
  32:     </Border>
  33: </DataTemplate>

Expose tile properties through APIs on ImageGridView Control

Now consumer of this user control can set the tile size and it will reflect in the view using databinding.

   1: //public constructor
   2: public ImageGridView()
   3: {
   4:     // Required to initialize variables
   5:     InitializeComponent();
   6:     _tileinfo = this.Resources["TileInfo"] as Tile;
   7: }
   8: 
   9: //height of each tile
  10: public double TileHeight
  11: {
  12:     get { return _tileinfo.TileHeight; }
  13:     set { _tileinfo.TileHeight = value; }
  14: }
  15: 
  16: //width of each tile
  17: public double TileWidth
  18: {
  19:     get { return _tileinfo.TileWidth; }
  20:     set { _tileinfo.TileWidth = value; }
  21: }
  22: 
  23: //padding around each tile applied as uniform thickness
  24: public Double TilePadding
  25: {
  26:     get { return _tileinfo.TilePadding.Top; }
  27:     set
  28:     {
  29:         //converts double value to uniform thickness value
  30:         _tileinfo.TilePadding = new Thickness((double)value);
  31:     }
  32: }

Build Slider that controls the size of tiles

Added markup for slider in my ImageGridView control

   1: <Slider HorizontalAlignment="Left" Margin="5,0,5,0"
   2:                 VerticalAlignment="Stretch" SmallChange="1"
   3:                 LargeChange="2" Value="5" Grid.Row="0"
   4:                 ValueChanged="Slider_ValueChanged"
   5:                 Width="200" Minimum="1"/>

hooked up the ValueChanged event that changes the size of the tile instance.

   1: private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
   2:         {
   3: 
   4:             _tileinfo.TileHeight = _tileinfo.TileHeight * e.NewValue/e.OldValue;
   5:             _tileinfo.TileWidth = _tileinfo.TileWidth * e.NewValue / e.OldValue;
   6:         }
Standard
Professional, Software

Part 5: Better Image Detail View

Technorati Tags: ,,

In Part 4, I was having some problems switching the thumbnail to full size image. I made some small changes to make it look better.

  1. I changed root layout panel from StackPanel to Grid.
  2. I also used animation (animating opacity ) to fade out thumbnail and fade in full size image.
  3. I added a progressbar control , but I only show it if I get downloadprogress event where download is greather than 0. otherwise it was showing progress with value 0 and before it could show anything, it was hiding it again.

DetailImage.xaml

1: <UserControl x:Class=”Search.DetailImage”2: xmlns=”http://schemas.microsoft.com/client/2007&#8243; 3: xmlns : x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221; 4: xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243; 5: xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243; 6: xmlns:control=”clr-namespace:Search;assembly=Search”7: xmlns:mycontrol=”clr-namespace:MyControls;assembly=MyControls”8: mc:Ignorable=”d” d:DesignWidth=”300″ d:DesignHeight=”300″ 9: >10: <UserControl.Resources>11: <control:UriConverter x:Key=”uriconverter”/>12: <control:ImageSourceConverter x:Key=”imagesourceconverter”/>13: <Storyboard x:Name=”ShowFullImage”>14: <DoubleAnimationUsingKeyFrames Storyboard.TargetName=”fullimage” Storyboard.TargetProperty=”(UIElement.Opacity)” BeginTime=”00:00:00″>15: <SplineDoubleKeyFrame KeyTime=”00:00:00″ Value=”0″/>16: <SplineDoubleKeyFrame KeyTime=”00:00:01″ Value=”1″/>17: </DoubleAnimationUsingKeyFrames>18: <DoubleAnimationUsingKeyFrames Storyboard.TargetName=”image” Storyboard.TargetProperty=”(UIElement.Opacity)” BeginTime=”00:00:00″>19: <SplineDoubleKeyFrame KeyTime=”00:00:00″ Value=”1″/>20: <SplineDoubleKeyFrame KeyTime=”00:00:01″ Value=”0″/>21: </DoubleAnimationUsingKeyFrames>22: </Storyboard>23:  24: </UserControl.Resources>25: <Grid x:Name=”LayoutRoot” >26: <Grid.RowDefinitions>27: <RowDefinition Height=”120″/>28: <RowDefinition Height=”*”/>29: </Grid.RowDefinitions>30: <Border BorderThickness=”2,2,2,2″ CornerRadius=”5,5,5,5″ Grid.Row=”0″ BorderBrush=”#FF000000″ >31: <StackPanel >32: <StackPanel Orientation=”Horizontal”>33: <TextBlock Text=”URL: “ FontWeight=”Bold” Margin=”10,0,0,0″/>34: <HyperlinkButton Content=”Link to Image” 35: FontSize=”15″ 36: NavigateUri=”{Binding Image.ImageURL,Converter={StaticResource uriconverter}}”37: TargetName=”_blank”/>38: </StackPanel>39: <StackPanel Orientation=”Horizontal”>40: <TextBlock Text=”Width (px): “ FontWeight=”Bold” Margin=”10,0,0,0″/>41: <TextBlock x:Name=”txtWidth” Text=”{Binding Image.ImageWidth}”/>42: </StackPanel>43: <StackPanel Orientation=”Horizontal”>44: <TextBlock Text=”Height (px):” FontWeight=”Bold” Margin=”10,0,0,0″/>45: <TextBlock x:Name=”txtHeight” Text=”{Binding Image.ImageHeight}”/>46: </StackPanel>47: <StackPanel Orientation=”Horizontal”>48: <TextBlock Text=”Size: (Bytes):” FontWeight=”Bold” Margin=”10,0,0,0″/>49: <TextBlock x:Name=”txtSize” Text=”{Binding Image.ImageFileSize}”/>50: </StackPanel> 51: <mycontrol:ProgressBar 52: x:Name=”progress” Height=”20″ 53: Margin=”0,5,0,5″ 54: VerticalAlignment=”Center” HorizontalAlignment=”Center” 55: Visibility=”Collapsed”/>56: </StackPanel>57: </Border>58: <Border 59: BorderThickness=”2,2,2,2″ CornerRadius=”5,5,5,5″ 60: BorderBrush=”#FF000000″ 61: Margin=”0,20,0,0″ x:Name=”imageborder” Grid.Row=”1″>62: <Grid>63: <Image 64: Margin=”5,5,5,5″ Stretch=”Fill” 65: Source=”{Binding Image.ThumbnailURL , Converter={StaticResource imagesourceconverter}}”66: RenderTransformOrigin=”0.5,0.5″ 67: x:Name=”image” 68: HorizontalAlignment=”Stretch”>69: <Image.RenderTransform>70: <TransformGroup>71: <ScaleTransform/>72: <SkewTransform/>73: <RotateTransform/>74: <TranslateTransform/>75: </TransformGroup>76: </Image.RenderTransform>77: </Image>78: <Image 79: Margin=”5,5,5,5″ Stretch=”Fill” 80: RenderTransformOrigin=”0.5,0.5″ 81: x:Name=”fullimage” 82: HorizontalAlignment=”Stretch”>83: <Image.RenderTransform>84: <TransformGroup>85: <ScaleTransform/>86: <SkewTransform/>87: <RotateTransform/>88: <TranslateTransform/>89: </TransformGroup>90: </Image.RenderTransform>91: </Image>92: </Grid>93: </Border>94: </Grid>95: </UserControl>

DetailImage.Xaml.cs

1: using System;2: using System.Windows;3: using System.Windows.Controls;4: using System.Windows.Media.Imaging;5: using Search.SearchService;6: using System.Net;7:  8: namespace Search9: {10: public partial class DetailImage : UserControl11: {12: #region Public Members13:  14: public DetailImage()15: {16: InitializeComponent();17: }18:  19: //sets the SearchResult. The reason why I had to expose this is because 20: //I need to know when the data context is changing so that I can do necessary21: //work to switch images from thumbnail to fullsize22: public Result SearchResult23: {24: get 25: {26: return _searchresult;27: }28: set 29: {30: _searchresult = value;31: //set the datacontext for the control32: DataContext = value;33: fullimage.Opacity = 0;34: image.Opacity = 100;35: BitmapImage bi = new BitmapImage(new Uri(_searchresult.Image.ImageURL, UriKind.Absolute));36: bi.DownloadProgress += new DownloadProgressEventHandler(bi_DownloadProgress);37: fullimage.Source = bi;38: }39: }40:  41: #endregion42:  43: #region Private Members44:  45: //when the full image is downloaded 46: //I switch the thumbnail image in detail view for full size47: void bi_DownloadProgress(object sender, DownloadProgressEventArgs e)48: {49:  50: if (e.Progress > 0 && e.Progress < 1)51: {52: progress.Visibility = Visibility.Visible;53: progress.Value = e.Progress * 100;54: }55: if (e.Progress == 1)56: {57: progress.Value = 100;58: ShowFullImage.Begin();59: progress.Visibility = Visibility.Collapsed;60: }61: }62:  63: Search.SearchService.Result _searchresult;64: #endregion65:  66: }67: }

here is the working project

Standard