这有点奇怪。 我在 .net MAUI Windows 应用程序的页面中有一个功能正常的 CollectionView。 当我说“正常运行”时,我的意思是:绑定数据(来自视图模型)已正确填充,并且集合视图正确显示它。
如果我向底层模型添加一个元素,它会正确更新,除非每次项目集合发生变化时,整个 CollectionView 都会刷新,这体现在 CollectionView 区域清除和项目淡入(如淡入动画) .
这是预期的行为吗?可以避免吗?
我非常确定当我添加项目时,项目集合不会被销毁或重新创建(这可以解释该行为)。任何建议都非常受欢迎,并提前表示赞赏。
只是为了完整性:每当将新项目添加到此 ItemsToList 可观察集合中时,就会发生问题,无论该项目是作为命令执行的一部分添加(如此处所示)还是通过任何其他方式添加。
视图文件中的相关代码(为了可读性进行了删节,但这就是本质):
<CollectionView
x:Name="messageCollectionView"
ItemsSource="{Binding ItemsToList}"
ItemsUpdatingScrollMode="KeepLastItemInView"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:ItemsToList">
<Grid
Padding="5">
<VerticalStackLayout>
<Label
Text="{Binding ItemName}" />
<Label
Text="{Binding ItemDescription}" />
</VerticalStackLayout>
</Grid>
</DataTemplate>
</CollectionView.Template>
</CollectionView>
<Button
Text="Add Item"
Command="{Binding AddITem}" />
相关型号代码:
public class ItemToList
{
public string? ItemName { get; set; }
public string? ItemDescription { get; set; }
}
相关视图模型代码(为了可读性进行了删节,但这就是它的本质):
public ObservableCollection<ItemToList> ItemsToList { get; } = [];
public ItemsToList()
{
this.ItemsToList = new ObservableCollection<ItemToList>();
}
[RelayCommand]
async Task AddItemToList()
{
var newItem = new ItemToList
{
ItemName = "Test 123",
ItemDescription = "The new item description here"
}
try
{
ItemsToList.Add(newItem);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
好吧,所以......无论它的价值:
我不认为这是问题的解决方案,但它确实为我提供了一种立即解决非常烦人的视觉“故障”的方法。
我为 CollectionView 实现了一个自定义处理程序,如下所示:
public partial class CustomCollectionViewHandler : CollectionViewHandler
{
protected override ListViewBase CreatePlatformView()
{
var repeater = base.CreatePlatformView();
DisableAnimations(repeater);
return repeater;
}
private void DisableAnimations(ListViewBase repeater)
{
repeater.ItemContainerTransitions = null;
}
}
我创建了方法
DisableAnimations
,这样就可以有选择地仅禁用其中的一些 - 尽管在我的情况下,我只需禁用所有这些方法就不会出现故障。
为了完整性:您应该能够有选择地仅禁用某些动画(例如,下面的示例中的不透明动画),但这对我来说并没有真正起作用(此代码将使用相同的
DisableAnimations
方法),我不知道为什么:
var transitionCollection = new TransitionCollection();
var addDeleteThemeTransition = new AddDeleteThemeTransition();
var repositionThemeTransition = new RepositionThemeTransition();
transitionCollection.Add(addDeleteThemeTransition);
transitionCollection.Add(repositionThemeTransition);
repeater.ItemContainerTransitions = transitionCollection;
无论如何,上面编码的自定义处理程序将使视觉故障变得不明显 - “刷新”仍在发生,你只是没有“看到它”,所以我仍在寻找问题本身的答案。
我已经进行了很多研究,这似乎可能与这个问题有关: https://github.com/dotnet/maui/issues/17369
现在,我会继续挖掘,也许有人提出这个问题并有一些建议或实际答案?