Pete Martin
Pete Martin

Reputation: 856

LongListSelector bound to ObservableCollection does not update

I have an ObservableCollection, which is a collection of View Models which implement the INotifyPropertyChanged interface...

public class FeedsViewModel : ObservableCollection<FeedViewModel>
{
}

(I have not included the code for FeedViewModel but it's quite standard INotifyPropertyChanged and binds when tested independently).

I am using an instance of FeedsViewModel as an ItemsSource in a LongListSelector control...

<UserControl.Resources>
    <viewModel:FeedStatusFeedbackConverter x:Key="ProgressStatusColorConverter"/>
    <viewModel:FeedStatusFeedbackConverter x:Key="TitleStatusColorConverter"/>
    <viewModel:FeedsViewModel x:Key="FeedsViewModel"/>
</UserControl.Resources>

<phone:LongListSelector ItemsSource="{Binding Source={StaticResource FeedsViewModel}}">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>

            <Grid x:Name="LayoutRoot" 
                  Background="{StaticResource PhoneChromeBrush}"
                  DataContext="{TemplateBinding}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>

                <Grid Grid.Column="0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>

                    <TextBlock Text="{Binding Path=Name}" 
                               Grid.Row="0"
                               Style="{StaticResource PhoneTextLargeStyle}"
                               Foreground="{Binding Path=Status, Converter={StaticResource TitleStatusColorConverter}}"/>
                    <TextBlock Text="{Binding Path=Uri}" 
                               Grid.Row="1"
                               Style="{StaticResource PhoneTextNormalStyle}" 
                               TextTrimming="WordEllipsis" />
                    <ProgressBar Grid.Row="2"
                                 Maximum="{Binding Path=ItemCount}"
                                 Value="{Binding Path=ItemProgress}"
                                 Foreground="{Binding Path=Status, Converter={StaticResource ProgressStatusColorConverter}}">
                    </ProgressBar>
                </Grid>

                <Grid Grid.Column="1">
                    <Image Name="Delete" 
                           Source="/Assets/Buttons/delete.png"
                           Width="48"
                           Height="48"
                           Margin="5"
                           MouseLeftButtonDown="Press"
                           MouseLeftButtonUp="Release"/>
                </Grid>
            </Grid>

        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>

However, when I add something to the ObservableCollection at runtime the UI is not updated with the change...

private void AddFeedClick(object sender, EventArgs e)
{
    var task = FeedModel.Load("Reddit");
    var awaiter = task.GetAwaiter();

    awaiter.OnCompleted(() =>
    {
        var model = awaiter.GetResult();
        FeedModel.Save(model);
        ((ObservableCollection<FeedViewModel>)Resources["FeedsViewModel"]).Add(new FeedViewModel(model));
    });
}

Hitting a breakpoint when the new view-model is added to the ObservableCollection and examining the collection shows that the CollectionChanged of the collection event has no handlers (is null).

How can I get the LongListSelector to update itself from the ObservableCollection?

Upvotes: 1

Views: 2330

Answers (2)

Pete Martin
Pete Martin

Reputation: 856

I resolved this problem by changing the cast in AddFeedClick from (ObservableCollection<FeedViewModel> to FeedsViewModel which is the actual type of the item. Although there was no invalid cast happening, there must have been some obscure OO feature at work here. I suspect that there are actually two, shadowed events on the collection, one for the ObservableCollection type and one for the extending type, but I do not know for sure.

Upvotes: 1

gleb.kudr
gleb.kudr

Reputation: 1508

  1. Try bind collection as item source from code instead of static binding (set List.ItemSource=collection). If CollectionChanged is null that means no subscribers to collection change.
  2. Also you may try to add items synchronously.

Upvotes: 1

Related Questions