Posts Tagged ‘Silverlight’
All Search Application Posts So Far…
Wanted to consolidate all search application posts so far
http://vivekdalvi.wordpress.com/2008/03/28/part-1-live-search-using-silverlight-main-page/
http://vivekdalvi.wordpress.com/2008/03/30/part-3-image-search-result-view/
http://vivekdalvi.wordpress.com/2008/04/06/part-4-image-detail-view/
http://vivekdalvi.wordpress.com/2008/04/15/part-5-better-image-detail-view/
http://vivekdalvi.wordpress.com/2008/04/21/part-6-slider-for-tile-size/
http://vivekdalvi.wordpress.com/2008/04/22/part-7-web-search-results/
http://vivekdalvi.wordpress.com/2008/04/24/part-8-3d-image-view-using-custom-layout/
http://vivekdalvi.wordpress.com/2008/04/25/part-9-image-size-filter/
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
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.
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.
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.