Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / WPF

iOS UIPickerView-like control in WPF

Rate me:
Please Sign up or sign in to vote.
4.95/5 (15 votes)
7 Nov 2011CPOL3 min read 59.3K   3.9K   21   26
Sample code and walkthrough for creating a UIPickerView (the "tumblers" UI common on the iPhone) control in WPF.

Introduction

In this article, I will describe a UIPickerView-like control I created using WPF. The UIPickerView is an iOS control for picking an item from a list via a tumbler. Typically, this control is associated with touch input, but I have found it to work well with the mouse as well. I can envision it being potentially useful in a desktop application, especially if a touch-enabled monitor is part of the system.

wpfuipicker.PNG

Background

A couple of months ago, while writing an article on user interface design, I was trying to think of different ways to construct a date/time control. One of the ideas I came up with was to use tumblers for the different date/time parts, just like in a UIPickerView control. During that exploration, I created a prototype WPF implementation. I have decided to clean up that prototype and share it with the CodeProject community.

Using the Code

Using the control is pretty straightforward. Simply include the WpfUIPickerLib namespace in your XAML file and create a WpfUIPickerControl element. There are only two custom dependency properties you need to be aware of:

  • AlwaysOpen: If set to True, WpfUIPickerControl will always be open and the tumblers will be visible. If set to False (the default), the control will look like a textbox displaying only the selected value(s). Clicking on the control will open it and the tumblers will then become visible, enabling the user to pick a new value. Clicking anywhere outside the control will close it (if AlwaysOpen is False).
  • Tumblers: This dependency property is a list of WpfUIPickerLib.TumblerData objects that represent the different tumblers you want to display. Each TumblerData instance represents a different tumbler in the control.

The following XAML demonstrates including the WpfUIPickerLib namespace and how to declare a WpfUIPickerControl object:

XML
<Window x:Class="WpfUIPicker.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfui="clr-namespace:WpfUIPickerLib;assembly=WpfUIPickerLib"
        Title="MainWindow" Height="300" Width="325"
        x:Name="thisWnd">
    <StackPanel>
        <TextBlock Text="WpfUIPickerControl with AlwaysOpen set to True" 
               HorizontalAlignment="Center" />
        <wpfui:WpfUIPickerControl HorizontalAlignment="Center" AlwaysOpen="True" 
           Tumblers="{Binding ApparelTumblers, ElementName=thisWnd}" />
        <TextBlock Text="WpfUIPickerControl with AlwaysOpen set to False" 
           HorizontalAlignment="Center" Margin="0,20,0,0"/>
        <wpfui:WpfUIPickerControl HorizontalAlignment="Center" 
           AlwaysOpen="False" Tumblers="{Binding DateTimeTumblers, ElementName=thisWnd}" />
    </StackPanel>
</Window>

The TumblerData object is a thin wrapper around the list of values you want to display in a single tumbler (ToString will be called on each value). It is needed by the control to trigger updates, to get/set the selected value, and to display a "seperator" (optional). Because I originally created this control for date/time, I wanted the "closed" version of the control to be able to display string tokens between tumbler values. For example, if I created three tumblers for the date (month, day, year), and the user picked 9 for the month, 5 for the day, and 2005 for the year, then I wanted the closed version of the control to display "09/05/2005". To support this usage, you can just set the string "/" to be the separator in the TumblerData object for the month and day tumblers. The TumblerData.Seperator property is ignored if the control is set to AlwaysOpen=true.

The following code demonstrates how to create TumblerData objects for a date/time implementation that supports dates from 1/1/1990 to 12/31/2011:

C#
public List<TumblerData> DateTimeTumblers
{
    get
    {
        List<TumblerData> retVal = new List<TumblerData>();
        List<int> years = new List<int>();
        for (int i = 1990; i < 2012; ++i)
            years.Add(i);

        List<string> months = new List<string>();
        for (int i = 1; i <= 12; ++i)
            months.Add(String.Format("{0:d2}", i));

        List<string> days = new List<string>();
        for (int i = 1; i <= 31; ++i)
            days.Add(String.Format("{0:d2}", i));

        List<string> hours = new List<string>();
        for (int i = 1; i <= 12; ++i)
            hours.Add(String.Format("{0:d2}", i));

        List<string> min = new List<string>();
        for (int i = 0; i < 60; ++i)
            min.Add(String.Format("{0:d2}", i));

        retVal.Add(new TumblerData(months, 8, "/"));
        retVal.Add(new TumblerData(days, 4, "/"));
        retVal.Add(new TumblerData(years, 12, ""));
        retVal.Add(new TumblerData(hours, 10, ":"));
        retVal.Add(new TumblerData(min, 0, ""));
        retVal.Add(new TumblerData(
               new string[] { "AM", "PM" }.ToList<object>(), 0, ""));
        return retVal;
    }
}

Points of Interest

WpfUIPickerControl supports three different ways to change the value of a tumbler: drag, mouse wheel, and just click on the desired value. The control implements "closed" by hiding non-selected values (hence the funky binding in the valueTemplate). Each tumbler is rendered as a StackPanel within a grid on a canvas. Drag is implemented by changing the Canvas.Top property on the grid.

History

The first iPhone was unveiled by Steve Jobs on January 9, 2007.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Siemens
United States United States
Mike Heydlauf is a Principal Informatics Engineer and Software Development Manager for Siemens Healthcare Diagnostics.

Mike is also a fisherman, a Brazilian Jiu Jitsu purple belt, a computer science hobbyist, a user experience evangelist, a mixed martial arts fight promoter, and a heck of a nice guy.

In his free time he enjoys spending time with his family and writing about himself in the third person.

A couple of Mike's personal software projects:

A physics-based puzzle game in WPF: http://www.blankscream.com/Default.aspx

A fun little practical joke App for the iPhone: http://www.detectorgadget.com

Comments and Discussions

 
GeneralMy vote of 4 Pin
Marco Balestri14-Nov-11 23:22
Marco Balestri14-Nov-11 23:22 
AnswerRe: My vote of 4 Pin
Mike Heydlauf17-Nov-11 4:59
professionalMike Heydlauf17-Nov-11 4:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.