WP7: Databinding to a ListPicker

Mar 19, 2011 at 8:23 PM

I'm trying to figure out how to databind to lists in WP7 using Caliburn.Micro, and I must be missing something simple. I have created a simple test project to try to isolate the issue, but I still can't figure it out.

My test project works like this:

  •  A singleton list object is created in the bootstrapper. The object's constructor adds several default items to the list. The singleton is injected into MainPageViewModel.
  • MainPageViewModel assigns the injected singleton to a public property.
  • My MainPage view includes a ListPicker from the Silverlight Toolkit for WP7. I am attempting to databind to it without success.

I have logging turned on, and I can see that the viewmodel property is being bound to the listpicker, but the items aren't showing up. I have also confirmed that the list does contain items at the point when it is injected into the viewmodel. I think the issue is in my item template, but I can't see where. Any suggestions?

Here's my XAML:

<phone:PhoneApplicationPage x:Class="Test.MainPage"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
                            xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                            FontFamily="{StaticResource PhoneFontFamilyNormal}"
                            FontSize="{StaticResource PhoneFontSizeNormal}"
                            Foreground="{StaticResource PhoneForegroundBrush}"
                            SupportedOrientations="Portrait"
                            Orientation="Portrait"
                            mc:Ignorable="d"
                            d:DesignWidth="480"
                            d:DesignHeight="768"
                            shell:SystemTray.IsVisible="True"
                            xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">

    <Grid x:Name="LayoutRoot">
        <toolkit:ListPicker x:Name="ListOfCities"
                            Height="100"
                            Margin="20,49,18,0"
                            VerticalAlignment="Top">
            <toolkit:ListPicker.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" />
                </DataTemplate>
            </toolkit:ListPicker.ItemTemplate>
        </toolkit:ListPicker>
    </Grid>
</phone:PhoneApplicationPage>

Here's the viewmodel:

namespace Test.ViewModels
{
    public class MainPageViewModel : PropertyChangedBase
    {
        public Cities ListOfCities { get; set; }

        public MainPageViewModel(Cities cities)
        {
            ListOfCities = cities;
        }
    }
}

And the code for the model:

namespace Test.Models
{
    public class Cities
    {
        public List<City> Items;

        public Cities()
        {
            Items = new List<City>();
            Items.Add(new City() { Name = "Madrid", Country = "ES", Language = "Spanish" });
            Items.Add(new City() { Name = "Las Vegas", Country = "US", Language = "English" });
            Items.Add(new City() { Name = "London", Country = "UK", Language = "English" });
            Items.Add(new City() { Name = "Mexico", Country = "MX", Language = "Spanish" });
        }
    }

    public class City
    {
        public string Name { get; set; }
        public string Country { get; set; }
        public string Language { get; set; }
    }
}
Mar 19, 2011 at 8:32 PM

Ha ha... I have been beating my head against the wall on this for about three hours, and then I post this and three minutes later I figure it out. I changed my viewmodel to expose the list of items from the Cities class:

namespace IoCTest.ViewModels
{
    public class MainPageViewModel : PropertyChangedBase
    {
        public Cities ListOfCities { get; set; }
        public List<City> GenericListOfCities { get; set; }

        public MainPageViewModel(Cities cities)
        {
            ListOfCities = cities;
            NotifyOfPropertyChange(() => ListOfCities);
            GenericListOfCities = cities.Items;
        }
    }
}