Visually Located

XAML and GIS

Responding to the Windows Phone Toolkit ListPicker closing

I’ve often wondered why the ListPicker in the Windows Phone Toolkit does not have an Opened or Closed event, especially since the SelectionChanged event fires only when the selection changes (as it should). So how are you suppose to know when the ListPicker opens or closes. After all, the ComboBox control has DropDownOpened and DropDownClosed. But then I thought, “Do you really need those? You can always use the IsDropDownOpened property.” The ListPicker does not have an Opened or Closed event and it does not have an IsDropDownOpened property. What the ListPicker does have, is the ListPickerMode property.

//
// Summary:
//     Gets or sets the ListPickerMode (ex: Normal/Expanded/Full).
public ListPickerMode ListPickerMode { get; }

This property is actually a DependencyProperty that we can bind to! Let’s say you need to change the visibility of another control when the ListPicker opens/closes. Or maybe you need to change some text based on the picker being opened. We can use the Expression SDK to change values within xaml. For this example we’ll look at changing text based on the picker being opened. We have the following xaml defined.

<StackPanel>
    <TextBlock Text="Closed" Style="{StaticResource PhoneTextLargeStyle}"/>
    <toolkit:ListPicker x:Name="Picker">
        <sys:String>Option one</sys:String>
        <sys:String>Option two</sys:String>
        <sys:String>Option three</sys:String>
        <sys:String>Option four</sys:String>
    </toolkit:ListPicker>
</StackPanel>

With the above xaml, we will always show “Closed”. Let’s start using the Expression SDK. The first step is to add the Microsoft.Expression.Interactions and System.Windows.Interactivity references to your project.

image

Next we need to add a DataTrigger to the TextBlock. The DataTrigger will respond to the ListPickerMode property changing and then change the text of the TextBlock.

<TextBlock  Text="Closed" Style="{StaticResource PhoneTextLargeStyle}">
    <i:Interaction.Triggers>
        <e:DataTrigger Binding="{Binding ListPickerMode, ElementName=Picker}" Value="Expanded">
            <e:ChangePropertyAction PropertyName="Text" Value="Open" TargetName="PickerState"/>
        </e:DataTrigger>
        <e:DataTrigger Binding="{Binding ListPickerMode, ElementName=Picker}" Value="Normal">
            <e:ChangePropertyAction PropertyName="Text" Value="Closed" TargetName="PickerState"/>
        </e:DataTrigger>
    </i:Interaction.Triggers>
</TextBlock>

Maybe you want to use a ValueConverter and show/hide the TextBlock based on the picker showing. First we’ll need to create a new ValueConverter.

public class PickerModeToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return Visibility.Collapsed;
 
        var mode = (ListPickerMode) value;
 
        return mode == ListPickerMode.Expanded ? Visibility.Visible : Visibility.Collapsed;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Next we’ll add the converter to the resources and use it to show the TextBlock.

<phone:PhoneApplicationPage.Resources>
    <local:PickerModeToVisibilityConverter x:Key="PickerModeConverter"/>
</phone:PhoneApplicationPage.Resources>
 
...
 
<TextBlock Text="Open" Style="{StaticResource PhoneTextLargeStyle}" 
           Visibility="{Binding ListPickerMode, ElementName=Picker, Converter={StaticResource PickerModeConverter}}" />

These were a couple of simple examples. You can do more by using the other built-in behaviors of the Expression SDK.

blog comments powered by Disqus