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.