ListView.ItemsSource: howto update the UI whenever the source is updated?
-
Tuesday, March 11, 2008 9:33 AMHi,
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:
This effectively updates the list, but not the UI.Code Snippetprivate void lstCalendars_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (this.lstCalendars.SelectedItems.Count > 0)
{
HybridCalendar calendar = (HybridCalendar)this.lstCalendars.SelectedItem;
calendar.Sync = !calendar.Sync;
}
}
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
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 PMI'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....

