I have a uno app where the observableCollection behaves differently on UWP and WASM platforms.
It occurs in a GridView with an ItemsWrapGrid specifed as the itemsPanel. The ItemSource is an ObservableCollection. This is the xaml:
<GridView x:Name="gView" ItemsSource="{Binding Pictures,Mode=OneWay}" SelectionMode="Extended" IsMultiSelectCheckBoxEnabled="False"
VerticalAlignment="Stretch" HorizontalAlignment="Center" SelectionChanged="ImageSelectionChanged" >
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="10"/>
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<not_wasm:ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="8"/>
<wasm:WrapPanel/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<Grid Margin="4">
<Image Source="{Binding URL}" Width="{Binding Parent.ImageWidth, Mode=TwoWay}" MinWidth="200"/>
<TextBlock Text="{Binding PictureKey}" Foreground="Yellow" FontSize="14" HorizontalAlignment="Center"
VerticalAlignment="Bottom" Margin="0,0,10,0"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The user is allows to select items and remove them from the view. This is the relevant code:
if (result == 1)
{
int ndx = vm.EvtViewModel.Pictures.IndexOf(pict);
vm.EvtViewModel.Pictures.Remove(pict);
if (ndx < vm.EvtViewModel.Pictures.Count)
{
vm.EvtViewModel.SelectedPicture = vm.EvtViewModel.Pictures[ndx];
}
else
{
vm.EvtViewModel.SelectedPicture = vm.EvtViewModel.Pictures.Count > 0 ? vm.EvtViewModel.Pictures.Last() : null;
}
}
where vm.EvtViewModel.Pictures is the ObservableCollection. The issue is that on UWP the items are removed and the remaining items below them are moved up the list. On WASM, it triggers a complete redraw of the Grid.
Is there a way to fix this?
There's no easy fix for this, but it'll be partially addressed in an upcoming Uno version. To understand the issue, note that you're using WrapPanel
on WebAssembly and ItemsWrapGrid
on UWP, which is the recommended approach since ItemsWrapGrid
isn't yet implemented for WASM.
WrapPanel
is a 'non-virtualizing' panel, meaning it eagerly creates views for all items in the items source. At present, non-virtualizing panels are not optimized for use with ObservableCollection
on WASM. This will be addressed by this change, which will prevent the entire grid being redrawn when a single item is inserted.