WP7 LoopingSelector in depth | Part1: Visual structure and API
published on: 12/3/2010 | Views: N/A | Tags: WP7Toolkit
by WindowsPhoneGeek
In the "WP7 LoopingSelector in depth" series of three posts I am going to talk about the key properties, methods, events and the main features of the Windows Phone 7 LoopingSelector in details.
- "Part1: Visual structure and API" I will explain the visual structure of this control, all about the available public API and I will give a simple example of NumericUpDown implementation .
- "Part2: Implementing a generic LoopingSelectorDataSource" I will talk about using the API and how to implement different LoopingSelector scenarios with Double, Int, String and DateTime data using a generic LoopingSelectorDataSource class.
- "Part3: Advanced data binding" - I will demonstrate how to implement advanced data binding scenarios with composite data.
One of the new components in the Silverlight Toolkit is the LoopingSelector which enables users to implement various looping scenarios in an easy way. Basically it is an infinite list selector which contains all the functionality for a looping control, all we need to do in order to use this component is just to provide an appropriate data source. We can create a suitable data source by implementing the ILoopingSelectorDataSource interface. In this article I will implement a numeric up down scenario using a simple numeric data source.
To begin using LoopinSelector first add a reference to the Microsoft.Phone.Controls.Toolkit.dll assembly which is installed with the toolkit and you can find it in :
C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.0\Toolkit\Nov10\Bin\Microsoft.Phone.Controls.Toolkit.dll.
You will also need to add the "toolkit" prefix declaration. Make sure that your page declaration includes the "toolkit" namespace:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone.Controls.Toolkit"
Note: LoopingSelector is in the Microsoft.Phone.Controls.Primitives namespace.
Note: DatePicker and TimePicker from the Silverlight for Windows Phone 7 toolkit are based on LoopingSelector.
Visual structure
The visual structure of LoopingSelector is very simple, it has two states: Expanded and Normal. The scheme is as follows:![]()
Note:Although LoopingSelecor can be populated with items it is not an ItemsControl and does not have any Items property! The only was you can add items to this control is through the DataSource property.
Note: Expanded and Normal states are not controlled by the VisualStateManager. So you will not be able to customize these states with a custom style.
LoopinSelector
Key Properties
- DataSource
DataSource is a dependency property of type ILoopingSelectorDataSource. It represents the data source of the control.
- IsExpanded
IsExpandedis a dependency property of type bool and it controls the expanded state of this control.
- ItemTemplate
ItemTemplate is a dependency property of type DataTemplate. It specifies the control ItemTemplate.
- ItemSize
ItemSize is a property of type Size. It specifies the size of the items, excluding the ItemMargin.
public Size ItemSize { get; set; }
- ItemMargin
ItemMargin is a property of type Thickness . It specifies the margin around the items, to be a part of the touchable area.
public Thickness ItemMargin { get; set; }
Events
- IsExpandedChanged
The IsExpandedChanged event will be raised whenever the IsExpanded state changes.
public event DependencyPropertyChangedEventHandler IsExpandedChanged;
ILoopingSelectorDataSource
This is the major interface that defines how the LoopingSelector communicates with data source.
Fields
- GetNext(object relativeTo)
Get the next datum, relative to an existing datum where "relativeTo" is the datum the return value will be relative to.
object GetNext(object relativeTo);
- GetPrevious(object relativeTo);
Get the previous datum, relative to an existing datum where "relativeTo" is the datum the return value will be relative to.
object GetPrevious(object relativeTo);
- SelectedItem
The selected item. Should never be null.
object SelectedItem { get; set; }
- SelectionChanged
Raised when the selection changes.
event EventHandler<SelectionChangedEventArgs> SelectionChanged;
Sample Usage - NumericUpDow implementation
In this example we will populate Loopingselector control in the easiest way using a numeric data source and the default build in ItemTemplate.
The first step is to create an instance of the LoopingSelector and lets set some ItemSize. The code is as follows:
<toolkit:LoopingSelector x:Name="selector" ItemMargin="2,3,3,2" ItemSize="100,100"/>
The next step is to begin creating the data source. We will divide the data source into two pieces: LoopingDataSourceBase and IntLoopingDataSource. At first we will create an abstract class: LoopingDataSourceBase that implement ILoopingSelectorDataSource . The purpose of this abstraction is to put all reusable code in a base class so that this will allow us to concentrate on the specifics (any specific logic for a particular data source) when implementing deriving looping data source classes. In our case we will put the selection logic in an abstract base class. The code is as follows:
// abstract the reusable code in a base class
// this will allow us to concentrate on the specifics when implementing deriving looping data source classes
public abstract class LoopingDataSourceBase : ILoopingSelectorDataSource
{
private object selectedItem;
#region ILoopingSelectorDataSource Members
public abstract object GetNext(object relativeTo);
public abstract object GetPrevious(object relativeTo);
public object SelectedItem
{
get
{
return this.selectedItem;
}
set
{
// this will use the Equals method if it is overridden for the data source item class
if (!object.Equals(this.selectedItem, value))
{
// save the previously selected item so that we can use it
// to construct the event arguments for the SelectionChanged event
object previousSelectedItem = this.selectedItem;
this.selectedItem = value;
// fire the SelectionChanged event
this.OnSelectionChanged(previousSelectedItem, this.selectedItem);
}
}
}
public event EventHandler<SelectionChangedEventArgs> SelectionChanged;
protected virtual void OnSelectionChanged(object oldSelectedItem, object newSelectedItem)
{
EventHandler<SelectionChangedEventArgs> handler = this.SelectionChanged;
if (handler != null)
{
handler(this, new SelectionChangedEventArgs(new object[] { oldSelectedItem }, new object[] { newSelectedItem }));
}
}
#endregion
}
Note: ILoopingSelectorDataSource is the most important part when using LoopingSelector control. In order to fit in the data source requirements each data source class should implement ILoopingSelectorDataSource (implementing ILoopingSelectorDataSource is expected by the LoopingSelector!).
After we have defined the abstract class it is time for the numeric data source implementation. We will create a IntLoopingDataSource class which derives from our LoopingDataSourceBase class. The class will represent a simple numeric up down looping of Int values. The code is as follows:
public class IntLoopingDataSource : LoopingDataSourceBase
{
private int minValue;
private int maxValue;
private int increment;
public IntLoopingDataSource()
{
this.MaxValue = 10;
this.MinValue = 0;
this.Increment = 1;
this.SelectedItem = 0;
}
public int MinValue
{
get
{
return this.minValue;
}
set
{
if (value >= this.MaxValue)
{
throw new ArgumentOutOfRangeException("MinValue", "MinValue cannot be equal or greater than MaxValue");
}
this.minValue = value;
}
}
public int MaxValue
{
get
{
return this.maxValue;
}
set
{
if (value <= this.MinValue)
{
throw new ArgumentOutOfRangeException("MaxValue", "MaxValue cannot be equal or lower than MinValue");
}
this.maxValue = value;
}
}
public int Increment
{
get
{
return this.increment;
}
set
{
if (value < 1)
{
throw new ArgumentOutOfRangeException("Increment", "Increment cannot be less than or equal to zero");
}
this.increment = value;
}
}
public override object GetNext(object relativeTo)
{
int nextValue = (int)relativeTo + this.Increment;
if (nextValue > this.MaxValue)
{
nextValue = this.MinValue;
}
return nextValue;
}
public override object GetPrevious(object relativeTo)
{
int prevValue = (int)relativeTo - this.Increment;
if (prevValue < this.MinValue)
{
prevValue = this.MaxValue;
}
return prevValue;
}
}
Note that we have added some validations for the Min/Max values and some Next/Previous logic in the GetNext/GetPrevious methods.
The final step is to populate the Loopingselector with our IntLoopingDataSource. The code is:
this.selector.DataSource = new IntLoopingDataSource() { MinValue = 1, MaxValue = 60, SelectedItem = 1 };
Note: We also used the MinValue = 1, MaxValue = 60, SelectedItem = 1 properties of our data source.
The result of this example can be seen in the next screenshots:
That was all about the basic usage of WP7 LoopingSelector control. We talked about VisualStructure, public API and sample populating with numeric data in the easiest way. In the next article "Part2: Implementing a generic LoopingSelectorDataSource" I will talk about how to implement different LoopingSelector scenarios with Double, Int, String and DateTime data using a generic LoopingSelectorDataSource class..
I hope that the article was helpful. The full source code is available here:
You can also follow us on Twitter @winphonegeek
Comments
Thank you for this Write up
posted by: Raghuraman on 12/28/2010 12:30:23 AM
Thank you very much for this write up.
It will definitely be very helpful in future for a lot of WP7/Silverlight programmers.
Regards and Cheers !!!
KRK
Source code link missing
posted by: Ra on 1/24/2011 6:48:39 AM
I noticed that the source link at the end of this article is missing. Could you please restore it? Great series, by the way. Thanks.
RE:Fixed Source code link
posted by: winphonegeek on 1/24/2011 11:03:42 AM
The link is already fixed. Thank you for the feedback.
Adding a label\Text to the selected item
posted by: JohnG on 7/25/2011 3:18:49 PM
Great series!
Any suggestions on how to add a Static label or heading to the SelectedItem ? i.e. Day or Weight, etc?
Issue
posted by: Sky on 8/14/2011 10:22:54 AM
Hey there, I sadly got stuck already at the beginning.
I pasted the code from second box, the public abstract class declaration, but it breaks with following error:
The type or namespace name'ILoopingSelectorDataSource' could notbe found
Maybe I paste it in a wrong place? Where should it be pasted?
also on the sidenote: in new SDK + VS2010 Express for Windows Phone you cannot find the Microsoft.Phone.Controls.Toolkit.dll file. LoopingSelector can be added in Expression Blend though - and this one takes care of all the code automatically. All that's left are classes supporting it (and that's the spot where I get stuck :( )
BTW: to the author - it'd be great to have one more sample tutorial: how to create loopingselector that works like select list in HTML. String as visible content for the user, int as value readable by the code, small & quick declaration of options + one sample line of reading the values selected by user. It'd be really awesome. I guess it's doable somehow with this tutorial, though appears to be very complicated & mixed for the beginner. :(
Like TimePicker AM PM
posted by: voka on 12/14/2011 4:04:04 PM
How can i use looping selector like AM,PM picker in control TimePicker of Silverlight Toolkit?
Our Top Articles & Free books
- Our FREE e-book: "Windows Phone Toolkit In Depth" 2nd edition
- 400+ Windows Phone Development articles in our Article Index
- 21 WP7 Toolkit in Depth articles covering all controls
- 12 WP7 Coding4Fun Toolkit in Depth articles covering all controls
- Performance Tips when creating WP7 apps
- Creating a WP7 Custom Control in 7 Steps
- WP7 working with VisualStates: How to make a ToggleSwitch from CheckBox
- What makes a WP7 App successful
- Creating theme friendly UI in WP7 using OpacityMask
- Implementing Windows Phone 7 DataTemplateSelector and CustomDataTemplateSelector
- All about Splash Screens in WP7 – Creating animated Splash Screen
- Getting Started with Unit Testing in Silverlight for WP7
- WP7 WatermarkedTextBox custom control
Our Top Tips & Samples
- All about WP7 Isolated Storage series
- WP7 Dynamically Generating DataTemplate in code
- 5 tips for a successful WP7 Marketplace submission
- WP7: Navigating to a page in different assembly
- WP7 ContextMenu: answers to popular questions
- WP7 ListBox: answers to popular questions
- WP7 working with Images: Content vs Resource build action
- WP7 Element Binding samples
- WP7 working with XML: reading, filtering and databinding
- Drawing in WP7: #2 Drawing shapes with finger
- WP7 TextBox Light theme problems - the solution
- Changing the WP7 Panorama Background Image dynamically with Animation
