我有一个绑定(bind)到 ListView
的 ObservableCollection
。此列表基本上是项目的选择。如果单击其中一个,它的状态就会改变。它被添加到收藏夹并显示在收藏夹列表(也是 ListView
)中,或者从收藏夹中删除。
这是我的应用程序的主要功能,因此会有很多添加和删除操作。更新时,这两个列表都很慢、有错误并且闪烁。
我怎样才能让它更快/更流畅?
我已经尝试在工作线程上运行所有添加/删除调用。我尝试过使用 Task
和 async
函数(这实际上使情况变得更糟)。这种情况是否有“适当”的实现?(ListView
ui 线程和工作线程保持最新)是否有一篇文章可以教我好的做法?
实现: 注意:Truck 是另一个存储数据的类。 来自数据类:
List<Truck> trucks = new List<Truck>();
public void addToFavorites(Truck truck)
{
foreach(Truck t in trucks)
{
if(t == truck)
{
t.setFavorite(true);
}
}
}
public void removeFromFavorites(Truck truck)
{
foreach (Truck t in trucks)
{
if (t == truck)
{
t.setFavorite(true);
}
}
}
public List<Truck> getTrucks()
{
return trucks;
}
public List<Truck> getFavoriteTrucks()
{
List<Truck> temp = new List<Truck>();
foreach(Truck t in trucks)
{
if (t.isFavorite())
{
temp.Add(t);
}
}
return temp;
}
从显示所有卡车的页面:
public partial class AllPage : ContentPage
{
public AllPage(csharp.Data data)
{
//init
InitializeComponent();
this.data = data;
//build list
refreshAsync();
ListView list = new ListView()
{
ItemTemplate = new DataTemplate(typeof(csharp.PlateCell)),
ItemsSource = trucks,
IsPullToRefreshEnabled = true,
};
//on select
list.ItemSelected += (sender, e) => {
if (e.SelectedItem == null) return; //row deselected, dont do anything
var selection = e.SelectedItem as csharp.Truck;
if (selection.isFavorite())
{
data.removeFromFavorites(selection);
selection.setFavorite(false);
}
else {
data.addToFavorites(selection);
selection.setFavorite(true);
}
((ListView)sender).SelectedItem = null; // de-select the row
refreshAsync();
};
list.RefreshCommand = new Command(() =>
{
//trucks = data.getFavoriteTrucks();
refreshAsync();
list.IsRefreshing = false;
});
//add the list to the page
root.Children.Add(list);
}//end constructor
csharp.Data data;
ObservableCollection<csharp.Truck> trucks = new ObservableCollection<csharp.Truck>();
private async Task refreshAsync()
{
await Task.Run(() => refreshThread());
}
private void refreshThread()
{
List<csharp.Truck> all = data.getTrucks();
trucks.Clear();
foreach (csharp.Truck t in all)
{
trucks.Add(t);
}
}
}
最佳答案
我认为一个很好的起点是让自己了解 Virtualizing
您应该避免在 GUI 线程以外的其他线程中更新您的可观察集合(参见 this)
一个好点也可以看看MVVM
据我所知,您将始终删除您的列表并重新填充它,而不是仅传播更改。 -> 这应该是您使用虚拟化的重点
您可能还想看看 this .使用 SmartCollection,您只会触发一次 CollectionChanged 事件,而不是针对您添加到列表中的每个项目
关于c# - 可以采取哪些步骤来优化 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39037869/