ListView.ItemsSource: howto update the UI whenever the source is updated?

Answered ListView.ItemsSource: howto update the UI whenever the source is updated?

  • Tuesday, March 11, 2008 9:33 AM
     
     
    Hi,

    I've got the following ListView:

    Code Snippet

    <ListView Name="lstCalendars" ScrollViewer.VerticalScrollBarVisibility="Visible" MouseDoubleClick="lstCalendars_MouseDoubleClick">
                    <ListView.View>
                        <GridView>                   
                            <!-- Title Column -->
                            <GridViewColumn>
                                <GridViewColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <Label Content="Calendar" Margin="2,0" HorizontalAlignment="Left"/>
                                    </DataTemplate>
                                </GridViewColumn.HeaderTemplate>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <Label Content="{Binding Path=Title}" HorizontalAlignment="Left">
                                            <Label.Style>
                                                <Style>
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding Path=Sync}" Value="True">
                                                            <Setter Property="Label.FontWeight" Value="Bold"/>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </Label.Style>
                                        </Label>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                           
                            <!-- Owner Column -->
                            <GridViewColumn>
                                <GridViewColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <Label Content="Owner" Margin="2,0" HorizontalAlignment="Left"/>
                                    </DataTemplate>
                                </GridViewColumn.HeaderTemplate>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <Label Content=""/>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>

                            <!-- Synchronize Column -->
                            <GridViewColumn>
                                <GridViewColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <Label Content="Synchronize" Margin="2,0"/>
                                    </DataTemplate>
                                </GridViewColumn.HeaderTemplate>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <CheckBox IsChecked="{Binding Path=Sync}" HorizontalAlignment="Center" HorizontalContentAlignment="Center"/>
                                    </DataTemplate>                       
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                           
                            <!-- Last Sync Column -->
                            <GridViewColumn>
                                <GridViewColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <Label Content="Last Sync" Margin="2,0" HorizontalAlignment="Left"/>
                                    </DataTemplate>
                                </GridViewColumn.HeaderTemplate>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <Label Content="" HorizontalAlignment="Left"/>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                           
                        </GridView>
                    </ListView.View>
                </ListView>


    I've got a List<HybridCalendar> calendars which I assign to the ItemsSource property of lstCalendars.
    This works great but the UI isn't automatically updated when the list is updated.

    For example, consider the following event handler:

    Code Snippet

    private void lstCalendars_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        if (this.lstCalendars.SelectedItems.Count > 0)
        {
            HybridCalendar calendar = (HybridCalendar)this.lstCalendars.SelectedItem;
            calendar.Sync = !calendar.Sync;
        }
    }


    This effectively updates the list, but not the UI.
    I could of course add this to the code:

    this.lstCalendars.Items.Refresh();

    But I'm guessing this is not the correct approach. I'd have to add this lots of times and it triggers a UI update
    for all the items in the list, which isn't something I'd want if the list became really long.

    Any suggestions?

All Replies

  • Tuesday, March 11, 2008 12:52 PM
     
     Answered

    This is because the List<T> class does not implement the INotifyCollectionChanged interface. The solution would be use either ObservableCollection<T> or your own Type that inherits from it (You could also create your own type and fully implement INotifyCollectionChanged, but this is rarely necessary).

     

     Note that one of the ObservableCollection<T> constructors takes a Generic List as a parameter and constructs its own inner list from it, so you could simply insantiate a new ObservableCollection(Of HybridCalendar)(yourList) and then set the ListView's ItemsSource to it. This should give you the immediate UI Update functionality you are looking for.

     

    Hope this helps,

     

    Keith

     

  • Tuesday, March 11, 2008 1:26 PM
     
     
    I'm now using
    private ObservableCollection<HybridCalendar> calendars;

    But I still have to call Items.Refresh() manually in order for UI changes to be visible... I'm missing something....