Adam S
Adam S

Reputation: 16394

Trouble with DataBinding to a ListBox in WP7 which is not displaying the bound content

I have a DataBinding on a ListBox, bound to an ObservableCollection. Debugging at runtime shows the ObservableCollection does have items in it, and they're not null. My code all looks fine, however for some reason nothing is being displayed in my ListBox. It definitely was working previously, however it no longer is - and I can't figure out why. I've examined previous versions of the code and found no differences that would have any effect on this - minor things like Width="Auto" etc.

I based my code off of the example found here:

http://msdn.microsoft.com/en-us/library/hh202876.aspx

So, my code:

XAML:

<phone:PhoneApplicationPage 
x:Class="MyNamespace.MyItemsListPage"
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:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <TextBlock Grid.Row="0" x:Name="PageTitle" Text="MyPageTitle" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <!-- Bind the list box to the observable collection. -->
        <ListBox x:Name="myItemsListBox" ItemsSource="{Binding MyItemsList}" Margin="12, 0, 12, 0" Width="440">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Stretch" Width="440">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="80" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock
                            Text="{Binding MyItemNumber}"
                            FontSize="{StaticResource PhoneFontSizeLarge}"
                            Grid.Column="0"
                            VerticalAlignment="Center" 
                            Margin="0,10"
                            Tap="TextBlock_Tap"/>
                        <TextBlock
                            Text="{Binding MyItemName}"
                            FontSize="{StaticResource PhoneFontSizeLarge}"
                            Grid.Column="1"
                            VerticalAlignment="Center"
                            Margin="0,10" 
                            Tap="TextBlock_Tap" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Grid>
</phone:PhoneApplicationPage>

C#:

namespace MyNamespace
{
public partial class MyItemsListPage : PhoneApplicationPage, INotifyPropertyChanged
{
    private static ObservableCollection<MyItem> _myItemsList;
    private ObservableCollection<MyItem> MyItemsList
    {
        get
        {
            return _myItemsList;
        }
        set
        {
            if (_myItemsList!= value)
            {
                _myItemsList= value;
                NotifyPropertyChanged("MyItemsList");
            }
        }

    }

    public MyItemsListPage ()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        HelperClass helper = new HelperClass();
        MyItemsList = helper.GetItems(this.NavigationContext.QueryString["query"]);
        base.OnNavigatedTo(e); // Breakpoint here shows "MyItemsList" has MyItem objects in it.
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify Silverlight that a property has changed.
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}
}

The Helper class is a connector to my read-only local database on the device. It returns an ObservableCollection<MyItem>:

public ObservableCollection<MyItem> GetItems(string itemName)
    {
        // Input validation etc.
        // Selecting all items for testing
        var itemsInDB =
            from MyItem item in db.Items
            select item;
        return new ObservableCollection<MyItem>(itemsInDB);
    }

And finally the MyItem class:

[Table]
public class MyItem: INotifyPropertyChanged, INotifyPropertyChanging
{
    private int _myItemId;

    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int MyItemId
    {
        ...
    }

    private string _myItemName;

    [Column(CanBeNull = false)]
    public string MyItemName
    {
        get
        {
            return _myItemName;
        }
        set
        {
            if (_myItemName!= value)
            {
                NotifyPropertyChanging("MyItemName");
                _myItemName= value;
                NotifyPropertyChanged("MyItemName");
            }
        }
    }

    private int _myItemNumber;
    [Column]
    public int MyItemNumber
    {
        get
        {
            return _myItemNumber;
        }
        set
        {
            if (_myItemNumber!= value)
            {
                NotifyPropertyChanging("MyItemNumber");
                _myItemNumber= value;
                NotifyPropertyChanged("MyItemNumber");
            }
        }
    }
    // Other properties, NotifyPropertyChanged method, etc...
}

This is rather frustrating as my DataBinding elsewhere in the application is working perfectly, so I've no idea why I can't get this to work.

Upvotes: 0

Views: 530

Answers (2)

Adam S
Adam S

Reputation: 16394

The problem was that my ObservableCollection was private. Changing it to have a public access modifier allowed my ListBox to display the contents:

public ObservableCollection<MyItem> MyItemsList

Upvotes: 1

o_q
o_q

Reputation: 81

Simply that you're binding to properties named incorrectly:

Text="{Binding ItemName}" should be Text="{Binding MyItemName}"

Notice you left out "My"

Upvotes: 0

Related Questions