ObservableCollection 的行为在 UWP 和 WASM 上不同
Behavior of ObservableCollection is different on UWP and WASM
我有一个 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>
用户可以 select 项并将其从视图中删除。这是相关代码:
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
isn't yet implemented for WASM.
WrapPanel
是一个 'non-virtualizing' 面板,这意味着它急切地为项目源中的所有项目创建视图。目前,非虚拟化面板未针对在 WASM 上与 ObservableCollection
一起使用进行优化。 this change 将解决此问题,这将防止在插入单个项目时重新绘制整个网格。
我有一个 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>
用户可以 select 项并将其从视图中删除。这是相关代码:
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
isn't yet implemented for WASM.
WrapPanel
是一个 'non-virtualizing' 面板,这意味着它急切地为项目源中的所有项目创建视图。目前,非虚拟化面板未针对在 WASM 上与 ObservableCollection
一起使用进行优化。 this change 将解决此问题,这将防止在插入单个项目时重新绘制整个网格。