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

Leave a comment