.net MAUI CollectionView - 每次更新时简要空白和重绘



使用。net MAUI,我有一个与包含自定义类的ObservableCollection绑定的CollectionView。数据绑定工作正常。对ObservableCollection的更新按预期在屏幕上反映。

然而,每次更新时,CollectionView都会消失一段时间,然后带着更新后的数据重新出现。这是一个问题,因为数据是以1hz的频率由后台线程更新的。因此,这种重绘对用户来说是一种不和谐的体验——列表总是短暂地空白,然后被重绘。

看这里的问题(转换为GIF有点模糊的完整效果):CollectionView更新与简短的空白

我已经搜索和搜索,但无法找到一种方法来获得CollectionView更新没有短暂的空白,然后重新绘制。我希望看到"顺利"。更新CollectionView,其中的子项只是在适当的地方更新,没有不和谐的空白/明显的刷新。有什么办法吗?

同样值得注意的是-我看到相同的空白+刷新行为与MonkeyFinder示例项目位于这里:https://github.com/dotnet-presentations/dotnet-maui-workshop。点击"获取猴子";导致页面空白,然后用相同的猴子列表刷新。因此,这个问题并不孤立于我在代码中所做的任何事情。

My CollectionView在XAML中的声明如下:

<CollectionView BackgroundColor="Transparent"
Grid.Column ="0" Grid.ColumnSpan="5"
Grid.Row="2"
ItemSizingStrategy="MeasureFirstItem"
ItemsSource="{Binding ResultsDataLC.SampleResults}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="json:SampleResult">
<Grid Padding="2" ColumnDefinitions="100,10,*" HeightRequest="50">
<Grid Grid.Column="0" Background="Transparent" ColumnDefinitions="*">
<Label Text="{Binding AOI, StringFormat='{0}'}" 
HorizontalTextAlignment="Center"  VerticalTextAlignment="Center"
HorizontalOptions="End" VerticalOptions="CenterAndExpand"
Background="Transparent"/>
</Grid>
<Border Grid.Column="2" Stroke="Black"
StrokeThickness="2"
WidthRequest="125"
HorizontalOptions="Start">
<Border.StrokeShape>
<RoundRectangle CornerRadius="10,10,10,10" />
</Border.StrokeShape>
<Border.Triggers>
<DataTrigger TargetType="Border"
Binding="{Binding Status}"
Value="{x:Static json:SampleStatusEnum.Positive}">
<Setter Property="Background"
Value="{StaticResource LightRed}" />
</DataTrigger>
<DataTrigger TargetType="Border"
Binding="{Binding Status}"
Value="{x:Static json:SampleStatusEnum.Negative}">
<Setter Property="Background"
Value="Limegreen" />
</DataTrigger>
<DataTrigger TargetType="Border"
Binding="{Binding Status}"
Value="{x:Static json:SampleStatusEnum.Testing}">
<Setter Property="Background"
Value="LightBlue" />
</DataTrigger>
<DataTrigger TargetType="Border"
Binding="{Binding Status}"
Value="{x:Static json:SampleStatusEnum.Inactive}">
<Setter Property="Background"
Value="Gray" />
</DataTrigger>
<DataTrigger TargetType="Border"
Binding="{Binding Status}"
Value="{x:Static json:SampleStatusEnum.Fault}">
<Setter Property="Background"
Value="Orange" />
</DataTrigger>
<DataTrigger TargetType="Border"
Binding="{Binding Status}"
Value="{x:Static json:SampleStatusEnum.Inactive}">
<Setter Property="Stroke"
Value="Black" />
</DataTrigger>
</Border.Triggers>
<Grid Padding="0" ColumnDefinitions="30,*,30" VerticalOptions="CenterAndExpand">
<CheckBox Grid.Column="0" IsChecked="{Binding Enabled}" IsVisible="false"/>
<Label Grid.Column="1" Text=""
HorizontalTextAlignment="Center" FontAttributes="Bold"/>
</Grid>
</Border>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>

我找到了适合我的特定实现的最佳解决方案。感觉更像是一种变通方法,但这是唯一对我有效的方法。

当我更新整个绑定的ObservableCollection时,所附图片中显示的空白发生,例如:

SampleResults = JsonConvert.DeserializeObject<ObservableCollection<SampleResult>>(deserialized.Message);
OnPropertyChanged(nameof(SampleResults));

我还尝试遍历ObservableCollection并简单地单独更新成员。这也导致了不稳定的GUI更新:

List<SampleResult> newResults = JsonConvert.DeserializeObject<List<SampleResult>>(deserialized.Message);
for (int i=0; i< newResults.Count; i++)
{
SampleResults[i] = newResults[i];
}

解决方案是遍历现有的ObservableCollection对象,并为集合中的每个项目单独更新成员。

这段代码的结果是平滑的GUI更新,没有跳转:

List<SampleResult> newResults = JsonConvert.DeserializeObject<List<SampleResult>>(deserialized.Message);
for (int i=0; i< newResults.Count; i++)
{
SampleResults[i].Status = newResults[i].Status;
SampleResults[i].Time = newResults[i].Time;
}

最新更新