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.
Here are few things I used in this…
- Custom Panels: Building Custom Layout
- 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.