Archive

Posts Tagged ‘metro’

Windows Phone 7 Pivot Indicator

December 25, 2011 3 comments

In this post I will explain how to add simple indicator to Windows Phone 7 Pivot Page, which tells user how many Pivot Items are in page and which Pivot Item is currently active. Indicator control is implemented as set of small circles bellow title where one circle which indicates active pivot item is accented (see picture bellow).

pivot indicator_sm

Pivot Control is great MetroUI control that is equivalent of desktop Tab control. Pivot orders the elements logically, splitting the information into categories and listing the elements available in each category. It is an analytical list used to show different aspects of the same content. But sometimes developers make mistakes and use Pivot Control in incorrectly. Let’s take look in next example. What is difference between these two pages?

not pivot app_sm pivot app_sm

These two pages look same, but first page is classic WP7 page and second one is Pivot page. In this case user is not aware that there are more Pivot items, because developer added captions that are too long. And I seen cases like this in several WP7 apps. But sometimes we need two words for pivot item captions.
Also, because of pivot control simplicity (which is great) user is not aware how many pivot items are in page. Users simply swipe pivot items left or right, and sometimes it is useful to have indicator that describes better context of current pivot navigation. In that case you can use Pivot Indicator shown above (I saw this indicator in one application but I cannot recall which). Let me describe how to create this indicator.

Add UserControl to your Pivot project and name it Indicator.xaml. Add horizontally oriented StackPanel on it. It will be used to dynamically add circles on later.

<Grid x:Name=”LayoutRoot” >
<StackPanel Name=”ellipsesPanelOrientation=”Horizontal” />
</Grid>

Add following code to UserControl:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace PivotIndicator
{
public partial class Indicator : UserControl
{
/// <summary>
/// Public ItemsCount property of type DependencyProperty
/// </summary>
public static readonly DependencyProperty ItemsCountProperty =
    DependencyProperty.Register(“ItemsCount“,
    typeof(int),
    typeof(Indicator),
    new PropertyMetadata(OnItemsCountChanged));

/// <summary>
/// Public SelectedPivotIndex property of type DependencyProperty
/// </summary>
public static readonly DependencyProperty SelectedPivotIndexProperty =
DependencyProperty.Register(“SelectedPivotIndex“,
typeof(int),
typeof(Indicator),
new PropertyMetadata(OnPivotIndexChanged));

/// <summary>
/// Constructor
/// </summary>
public Indicator()
{
InitializeComponent();
}

/// <summary>
/// Gets or sets number of pivot items
/// </summary>
public int ItemsCount
{
set { SetValue(ItemsCountProperty, value); }
get { return (int)GetValue(ItemsCountProperty); }
}

/// <summary>
/// Gets or sets index of selected pivot item
/// </summary>
public int SelectedPivotIndex
{
    set { SetValue(SelectedPivotIndexProperty, value); }
    get { return (int)GetValue(SelectedPivotIndexProperty); }
}

/// <summary>
/// OnItemsCountChanged property-changed handler
/// </summary>
private static void OnItemsCountChanged(DependencyObject obj,     DependencyPropertyChangedEventArgs args)
{
(obj as Indicator).SetCircles();
}

/// <summary>
/// OnPivotIndexChanged property-changed handler
/// </summary>
private static void OnPivotIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
(obj as Indicator).AccentCircle();
}

/// <summary>
/// Draws circles.
/// </summary>
private void SetCircles()
{
ellipsesPanel.Children.Clear();
for (int i = 0; i < this.ItemsCount; i++)
{
Ellipse ellipse = new Ellipse() { Height = 10, Width = 10, Margin = new Thickness(2,0,0,0) };
ellipsesPanel.Children.Add(ellipse);
}
this.AccentCircle();
}

/// <summary>
/// Accents selected pivot item circle.
/// </summary>
private void AccentCircle()
{
int i = 0;
foreach (var item in ellipsesPanel.Children)
{
if (item is Ellipse)
{
Ellipse ellipse = (Ellipse)item;
if (i == this.SelectedPivotIndex)
ellipse.Fill = (SolidColorBrush)Application.Current.Resources[“PhoneForegroundBrush“];
else
ellipse.Fill = (SolidColorBrush)Application.Current.Resources[“PhoneDisabledBrush“];
i++;
}
}
}

}
}

We have two dependency properties; ItemsCount and SelectedPivotIndex, and two methods; SetCircles() – which is called each time when we add new pivot item, and AccentCircle() – which is called each time when another pivot item is selected.
Now add Indicator control to you Pivot page. Name your Pivot control as “myPivot” and add Pivot control header TitleTemplate:

<!–Pivot Control–>
<controls:Pivot Name=”myPivotTitle=”MY APPLICATION“>

<!–Pivot Control Header–>
<controls:Pivot.TitleTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text=”MY APPLICATION“/>
<my:Indicator x:Name=”Indicator1VerticalAlignment=”Top” >
<my:Indicator.ItemsCount>
<Binding ElementName=”myPivotPath=”Items.Count“/>
</my:Indicator.ItemsCount>
<my:Indicator.SelectedPivotIndex>
<Binding ElementName=”myPivotPath=”SelectedIndex“/>
</my:Indicator.SelectedPivotIndex>
</my:Indicator>
</StackPanel>
</DataTemplate>
</controls:Pivot.TitleTemplate>

    <controls:PivotItem Header=”first” />

    <controls:PivotItem Header=”second” />

    <controls:PivotItem Header=”third” />

</controls:Pivot>

In this way Indicator control is directly binded to Pivot control Items.Count and SelectedIndex property, and on each change of these properties circles in Indicator control will be automatically redrawn, even in design mode.
And that is it. If you have more than three pivot items decide if you want to add this simple, but efficient control to your pivot page.
Complete code with solution can be downloaded from here.

Advertisements
Categories: Windows Phone Tags: , , ,