Dherik Dherik - 2 months ago 13
C# Question

Windows Phone: ListBox cannot show added items

I'm trying to display added elements in a ObservableCollection to show on a ListBox in a Page (MenuPage).

This collection is fed by another page, called AddActivityAdvancedPage. In the AddActivityAdvancedPage, the user fill the form and save the informations that I send it as a object (pmaActivity) to the MenuPage. The MenuPage receive the object and add on the ObservableCollection.

The problem is that my ObservableCollection not hold the the added itens! The itens are not showed on the ListBox.

I debug the code and everytime the application hit the line

ListActivitiesAdvanced.Add(pmaActivity);
on the MenuPage, the ListActivitiesAdvanced is empty. I need to set the ListActivitiesAdvanced as static in some way, but I don't know how is the right way to do this.

AddActivityAdvancedPage class:

public partial class AddActivityAdvancedPage : PhoneApplicationPage
{

//method called to pass the object pmaActivity as parameter to the MenuPage
private void btnSave_Click(object sender, EventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
PhoneApplicationService.Current.State.Remove("pmaActivity");
PhoneApplicationService.Current.State["pmaActivity"] = pmaActivity;
NavigationService.Navigate(new Uri("/MenuPage.xaml", UriKind.Relative));
});
}

}


MenuPage class:

public partial class MenuPage : PhoneApplicationPage
{
public ObservableCollection<PmaActivity> ListActivitiesAdvanced { get; set; }

public MenuPage()
{
InitializeComponent();
ListActivitiesAdvanced = new ObservableCollection<PmaActivity>();
}

//Method called to receive the pmaActivity and add in the collection
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (PhoneApplicationService.Current.State.ContainsKey("pmaActivity"))
{
PmaActivity pmaActivity = PhoneApplicationService.Current.State["pmaActivity"] as PmaActivity;
PhoneApplicationService.Current.State.Remove("pmaActivity");
ListActivitiesAdvanced.Add(pmaActivity);
}
}
}


ListBox in the MenuPage:

<ListBox ItemsSource="{Binding ListActivitiesAdvanced}" Margin="0,0,12,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="105" >
<Border BorderThickness="1" Width="73" Height="73" BorderBrush="#FF005DFF" Background="#FF005DFF" Margin="0,10,8,0" VerticalAlignment="Top"/>
<StackPanel Width="370">
<TextBlock Text="{Binding clientName}" TextWrapping="NoWrap"
Margin="12,0,0,0" Style="{StaticResource PhoneTextLargeStyle}"/>
<TextBlock Text="{Binding projectName}" TextWrapping="NoWrap"
Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>


I try to remove the ListActivitiesAdvanced from MenuPage and add a x:Name to the ListBox element with the same name: ListActivitiesAdvanced:

<ListBox x:Name="ListActivitiesAdvanced" Margin="0,0,12,0"/>


But in this case, the problem is that this list not hold the previous added itens! Every time I add an item, only the last item added is showed on the ObservableCollection.

Thanks for any help! I'm really have problems with that, there are a lot of ways to bind lists in ListBox (as StaticResource, Source, Binding, List, ObservableCollection, IEnumerable...) and I cannot understand all the differences.

Answer

If you want to persist the item list, then why not just put the full list into the application state?

//method called to pass the object pmaActivity as parameter to the MenuPage
private void btnSave_Click(object sender, EventArgs e)
{
    Dispatcher.BeginInvoke(() =>
    {
        List<PmaActivity> activities;
        if (PhoneApplicationService.Current.State.ContainsKey("pmaActivities"))
            activities = PhoneApplicationService.Current.State["pmaActivities"];
        else
            activities = new List<PmaActivity>();
        activities.Add(pmaActivity);
        PhoneApplicationService.Current.State["pmaActivities"] = pmaActivities;
        NavigationService.Navigate(new Uri("/MenuPage.xaml", UriKind.Relative));
    });
}

Then in the main page, populate from the list:

//Method called to receive the pmaActivity and add in the collection
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (PhoneApplicationService.Current.State.ContainsKey("pmaActivity"))
    {
        if (PhoneApplicationService.Current.State.ContainsKey("pmaActivities"))
        {
            var pmaActivities = PhoneApplicationService.Current.State["pmaActivities"] as List<PmaActivity>;
            foreach (var activity in pmaActivities)
                ListActivitiesAdvanced.Add(activity);
        }
    }