Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Revision as of 17:22, 18 July 2014 by somnathbanik (Talk | contribs)

People Hub Tile Control In Windows Phone

From Wiki
Jump to: navigation, search

This article demonstrate how to create People Hub Tile using Custom Control in Windows Phone.

WP Metro Icon UI.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
Code ExampleTested with
Devices(s): Nokia Lumia 820,920
CompatibilityArticle
Created: somnathbanik (18 Jul 2014)
Last edited: somnathbanik (18 Jul 2014)

Contents

Introduction

In this article we will create People Hub Tile using Custom Control. If you are new to custom control I would encourage you to have a look to my last article for more details about custom controls. User can add the reference of the People Hub Tile control in the main project and can access the control from XAML.

Implementation

Create a standard Windows Phone Project

Let’s create a standard Windows Phone Application Project

  • Launch Visual Studio
  • Click on File
  • Click on New Project
  • Select Windows Phone App (Visual C# Template)
  • Add Name and Location of the project
  • Click OK to create the project.

Create a Custom Control Project

  • Right Click on “Project Solution”
  • Click on “Add”
  • Select “New Project”
  • Select “Windows Phone Class Library”
  • Add Name and Location of the project
  • Click OK to create the project.
  • Now create a “Themes” folder in the project
  • Create “generic.xaml” file inside the “Themes” folder, and make sure the “Build Action” of the “generic.xaml” is set to “Resource”.
  • Create a class file “PeopleHubTile.cs” into the project.
  • Finally add the Custom Control project reference to your main project.


Creating UI

  • Before starting to write code in the project make sure you have added few images in the project; in this example we have created an image folder inside Themes and put some images into it. Now you are ready to write code in your project. Open the generic.xaml file and add ListBox control inside ControlTemplate. This ListBox will display the images on certain time intervals. For better presentation we created a DataTemplate of the ListBox.


<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:local="clr-namespace:PeopleHubTileEx">
<DataTemplate x:Key="DataTemplatePeopleHubTile">
<Grid x:Name="TileGrid" Height="80" Width="80" >
<Grid.Projection>
<PlaneProjection RotationX="{Binding RotationX}" CenterOfRotationY="{Binding CenterOfRotationX}">
</PlaneProjection>
</Grid.Projection>
<Grid x:Name="BackGrid" Canvas.ZIndex="{Binding ZIndex}" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform ScaleY="-1"/>
</Grid.RenderTransform>
<Grid.Background>
<SolidColorBrush Color="Green"></SolidColorBrush>
</Grid.Background>
<Image Source="{Binding TileData.ImageBack}" Stretch="Fill" />
</Grid>
<Grid x:Name="FrontGrid">
<Grid.Background>
<SolidColorBrush Color="Green"></SolidColorBrush>
</Grid.Background>
<Image Source="{Binding TileData.ImageFront}" Stretch="Fill" >
</Image>
</Grid>
</Grid>
</DataTemplate>
<Style TargetType="local:PeopleHubTile">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:PeopleHubTile">
<Grid>
<ListBox Name="ItemsListBox" Width="240" Height="240"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ItemTemplate="{StaticResource DataTemplatePeopleHubTile}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel ItemHeight="80" ItemWidth="80" Orientation="Horizontal">
</toolkit:WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

The DataTemplate of the ListBox has two Image control for display front and back of the tiles.

Code Behind

  • In PeopleHubTile.cs file first we load the images in a collection and set it to ListBox ItemsSource
void PeopleHubTile_Loaded(object sender, RoutedEventArgs e)
{
ItemsListBox = this.GetTemplateChild("ItemsListBox") as ListBox;
this.ItemsListBox.ItemsSource = dataItems;
dispatcherTimer.Interval = TimeSpan.FromSeconds(2);
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Start();
}
  • The main and core component of this custom control is to flip the images on a certain time intervals. So we set a DispatcherTimer with a time interval of 2 seconds. Every after 2 seconds we pick an image randomly and set it in the front or back of a randomly selected tile from the ListBox. This logic will change the images of the tiles on a time interval. To display a big image we wait for a certain rotation of intervals and then for each tile we set the portion of the selected image. This way a four tiles display a complete big image.
void dispatcherTimer_Tick(object sender, EventArgs e)
{
TileAnimationCount++;
if (TileAnimationCount > 9 && isReadyForBigTile == false)
{
TileAnimationCount = 0;
isReadyForBigTile = true;
}
int AnimateItem = 0;
Tiles AnimateTile = null;
if (!isBigTileAnimationStarted)
{
AnimateItem = RandomTile.Next(this.dataItems.Count);
AnimateTile = this.dataItems[AnimateItem];
if (isReadyForBigTile && (AnimateItem == 0 || AnimateItem == 1 || AnimateItem == 3 || AnimateItem == 4))
{
LastAnimatedTile = AnimateItem;
isBigTileAnimationStarted = true;
TileAnimateIndex = 0;
}
/// Animate small tiles
if (AnimateTile.ZIndex == 0)
{
//back tile
PeopleHubTileData ItemData = AnimateTile.TileData as PeopleHubTileData;
int newImage = RandomTile.Next(ImageUrl.Count);
if (RandomTile.Next(20) > 5)
ItemData.ImageBack = new BitmapImage(new Uri(ImageUrl[newImage], UriKind.RelativeOrAbsolute));
else
ItemData.ImageBack = new BitmapImage(new Uri("", UriKind.RelativeOrAbsolute));
}
else if (AnimateTile.ZIndex != 0)
{
//front tile
PeopleHubTileData ItemData = AnimateTile.TileData as PeopleHubTileData;
int newImage = RandomTile.Next(ImageUrl.Count);
if (RandomTile.Next(20) > 5)
ItemData.ImageFront = new BitmapImage(new Uri(ImageUrl[newImage], UriKind.RelativeOrAbsolute));
else
ItemData.ImageFront = new BitmapImage(new Uri("", UriKind.RelativeOrAbsolute));
}
}
else if (isBigTileAnimationStarted && TileAnimateIndex < 4)
{
int[] LastTiles = new int[4];
switch (LastAnimatedTile)
{
case 0:
LastTiles = new int[4] { 0, 1, 3, 4 };
break;
case 1:
LastTiles = new int[4] { 1, 2, 4, 5 };
break;
case 3:
LastTiles = new int[4] { 3, 4, 6, 7 };
break;
case 4:
LastTiles = new int[4] { 4, 5, 7, 8 };
break;
default:
break;
}
 
AnimateTile = this.dataItems[LastTiles[TileAnimateIndex]];
if (!isBitImageSelected)
{
isBitImageSelected = true;
BitImageSelectedIndex = RandomTile.Next(ImageUrl.Count);
}
BitmapImage bmpWB = new BitmapImage(new Uri(ImageUrl[BitImageSelectedIndex], UriKind.RelativeOrAbsolute));
WriteableBitmap ImageWB = new WriteableBitmap(bmpWB.PixelWidth, bmpWB.PixelHeight);
bmpWB.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap imageBitMap = new WriteableBitmap(bmpWB);
switch (TileAnimateIndex)
{
case 0:
ImageWB = GetCropImage(imageBitMap, 0, 0, imageBitMap.PixelWidth / 2, imageBitMap.PixelHeight / 2);
break;
case 1:
ImageWB = GetCropImage(imageBitMap, imageBitMap.PixelWidth / 2, 0, imageBitMap.PixelWidth / 2, imageBitMap.PixelHeight / 2);
break;
case 2:
ImageWB = GetCropImage(imageBitMap, 0, imageBitMap.PixelHeight / 2, imageBitMap.PixelWidth / 2, imageBitMap.PixelHeight / 2);
break;
case 3:
ImageWB = GetCropImage(imageBitMap, imageBitMap.PixelWidth / 2, imageBitMap.PixelHeight / 2, imageBitMap.PixelWidth / 2, imageBitMap.PixelHeight / 2);
break;
default:
break;
}
TileAnimateIndex++;
if (TileAnimateIndex > 3)
{
isBigTileAnimationStarted = false;
isReadyForBigTile = false;
isBitImageSelected = false;
}
//animate part of big tiles
if (AnimateTile.ZIndex == 0)
{
//back tile
PeopleHubTileData ItemData = AnimateTile.TileData as PeopleHubTileData;
ItemData.ImageBack = ImageWB;
}
else if (AnimateTile.ZIndex != 0)
{
//front tile
PeopleHubTileData ItemData = AnimateTile.TileData as PeopleHubTileData;
ItemData.ImageFront = ImageWB;
}
//tile animation
Storyboard MyStory = new Storyboard();
DoubleAnimation MyDouble = new DoubleAnimation();
MyDouble.From = AnimateTile.RotationX;
MyDouble.To = AnimateTile.RotationX + 180;
MyDouble.Duration = TimeSpan.FromSeconds(0.5);
Storyboard.SetTarget(MyDouble, AnimateTile);
Storyboard.SetTargetProperty(MyDouble, new PropertyPath(Tiles.RotationXProperty));
MyStory.Children.Add(MyDouble);
ObjectAnimationUsingKeyFrames MyObject = new ObjectAnimationUsingKeyFrames();
DiscreteObjectKeyFrame MyKeyFrame = new DiscreteObjectKeyFrame();
MyKeyFrame.KeyTime = TimeSpan.FromSeconds(0);
MyKeyFrame.Value = AnimateTile.ZIndex;
MyObject.KeyFrames.Add(MyKeyFrame);
MyKeyFrame = new DiscreteObjectKeyFrame();
MyKeyFrame.KeyTime = TimeSpan.FromSeconds(0.3);
MyKeyFrame.Value = (AnimateTile.ZIndex == 0) ? 1 : 0;
MyObject.KeyFrames.Add(MyKeyFrame);
Storyboard.SetTarget(MyObject, AnimateTile);
Storyboard.SetTargetProperty(MyObject, new PropertyPath(Tiles.ZIndexProperty));
MyStory.Children.Add(MyObject);
MyStory.Begin();
}

Adding custom control in main project

  • Open MainPage.xaml and add the namespace
  xmlns:PeopleHubTileControl="clr-namespace:PeopleHubTileEx;assembly=PeopleHubTileEx"
  • Now to display the control add the below code in the MainPage.xaml
  <PeopleHubTileControl:PeopleHubTile  VerticalAlignment="Center">
</PeopleHubTileControl:PeopleHubTile>

Summary

  • While working in this example I went through this article which helps me to understand better about tile animation. There are many code sections which are not added in this article to make it simple and focused. I would encourage you to download the source code to get a real experience about this example.

Source Code

336 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×