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:         }
Advertisements
Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s