我有一个uno应用程序,其中observableCollection在UWP和WASM平台上的行为不同。
它发生在GridView中,ItemsWrapGrid指定为itemsPanel。ItemSource是一个ObservableCollection。这是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>
用户可以从视图选择项和删除它们。这是相关代码:
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;
}
}
其中vm.EvtViewModel.Pictures是ObservableCollection。的问题是,UWP下面的项目删除,其余项目都上升。在WASM上,它触发网格的完全重绘。
有办法解决这个问题吗?
要解决这个问题并不容易,但它将在即将到来的Uno版本中得到部分解决。要理解这个问题,请注意您在WebAssembly上使用WrapPanel
,在UWP上使用ItemsWrapGrid
,这是推荐的方法,因为ItemsWrapGrid
尚未在WASM上实现。
WrapPanel
是一个"非虚拟化"面板,这意味着它急切地为项目源中的所有项目创建视图。目前,非虚拟化面板没有针对WASM上的ObservableCollection
进行优化。这将通过此更改来解决,这将防止在插入单个项目时重新绘制整个网格。