,

Providing Custom Looping Lists with the LoopingSelector

The previous section looked at the DatePicker and TimePicker controls, whose base class, DateTimePickerBase, relies on a simpler control called LoopingSelector to display date and time values.

LoopingSelector provides all the functionality for an infinitely looping list of values.

LoopingSelector is not intended to be used day-to-day like other controls presented in this chapter, and as a result it resides in the Microsoft.Phone.Controls.Primitives namespace. Nonetheless, it is a useful control.

To use the control you must define a data source, which can be any object that implements ILoopingSelectorDataSource. The ILoopingSelectorDataSource interface defines the following four members:

Image GetPrevious(object relativeTo) method

Image GetNext(object relativeTo) method

Image SelectedItem property

Image SelectionChanged event

GetPrevious and GetNext allow you to define the order of the data provided to the control. SelectedItem is used to keep track of the currently selected item in the control. The SelectionChanged event allows you to programmatically change the selected item in the control, which is normally done via the SelectedItem property.

To present a selectable list of numeric values to the user, we create an ILoopingSelectorDataSource called NumericDataSource (see Listing 9.4).

NumericDataSource allows you to define a range of integers using two properties: Minimum and Maximum.

LISTING 9.4. NumericDataSource Class


public class NumericDataSource : ILoopingSelectorDataSource
{
    public event EventHandler<SelectionChangedEventArgs> SelectionChanged;

    protected virtual void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        EventHandler<SelectionChangedEventArgs> tempEvent = SelectionChanged;
        if (tempEvent != null)
        {
            tempEvent(this, e);
        }
    }

    public object GetNext(object relativeTo)
    {
        int nextValue = (int)relativeTo + 1;

        return nextValue <= Maximum ? nextValue : Minimum;
    }

    public object GetPrevious(object relativeTo)
    {
        int previousValue = (int)relativeTo - 1;

        return previousValue >= Minimum ? previousValue : Maximum;
    }
    int selectedItem = 1;

    public object SelectedItem
    {
        get
        {
            return selectedItem;
        }
        set
        {
            int newValue = (int)value;

            if (selectedItem == newValue)
            {
                return;
            }
            int oldValue = selectedItem;
            selectedItem = newValue;

            OnSelectionChanged(new SelectionChangedEventArgs(
                                        new[] {oldValue}, new[] {newValue}));
        }
    }

    public int SelectedNumber
    {
        get
        {
            return (int)SelectedItem;
        }
        set
        {
            SelectedItem = value;
        }
    }

    int minimum = 1;

    public int Minimum
    {
        get
        {
            return minimum;
        }
        set
        {
            minimum = value;
            if (selectedItem < minimum)
            {
                SelectedItem = value;
            }
        }
    }

    int maximum = 100;

    public int Maximum
    {
        get
        {
            return maximum;
        }
        set
        {
            maximum = value;

            if (selectedItem > maximum)
            {
                SelectedItem = value;
            }
        }
    }
}


To use the NumericDataSource, we expose an instance via a property in a viewmodel, like so:

NumericDataSource numericDataSource
  = new NumericDataSource { Minimum = 0, Maximum = 10, SelectedNumber = 5 };

public NumericDataSource NumericDataSource
{
    get
    {
        return numericDataSource;
    }
}

A LoopingSelector can be data bound to the NumericDataSource property in the viewmodel. Its ItemTemplate defines the appearance of each item retrieved from the data source. See the following example:

<toolkitPrimitives:LoopingSelector
    DataSource="{Binding NumericDataSource}"
    Margin="12" Width="200" Height="500" ItemSize="128,128">
    <toolkitPrimitives:LoopingSelector.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding}" FontSize="54"
                    FontFamily="{StaticResource PhoneFontFamilySemiBold}"
                    HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Grid>
        </DataTemplate>
    </toolkitPrimitives:LoopingSelector.ItemTemplate>
</toolkitPrimitives:LoopingSelector>

It is critical to assign values to the LoopingSelector element’s Width, Height, and ItemSize properties.

Figure 9.20 shows the LoopingSelector after it has gained focus.

Image

FIGURE 9.20 LoopingSelector example.

LoopingSelector is a control ideally suited to the touch-centric environment of the phone.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.160.63