c# - 可以采取哪些步骤来优化 ListView

标签 c# xamarin.forms

我有一个绑定(bind)到 ListViewObservableCollection。此列表基本上是项目的选择。如果单击其中一个,它的状态就会改变。它被添加到收藏夹并显示在收藏夹列表(也是 ListView)中,或者从收藏夹中删除。

这是我的应用程序的主要功能,因此会有很多添加和删除操作。更新时,这两个列表都很慢、有错误并且闪烁。

我怎样才能让它更快/更流畅?

我已经尝试在工作线程上运行所有添加/删除调用。我尝试过使用 Taskasync 函数(这实际上使情况变得更糟)。这种情况是否有“适当”的实现?(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/

相关文章:

c# - .Net/C# 中远程启动和关闭 Azure 服务器

c# - XAML 等效于 HTML 标题属性

ios - 无法验证 MYAPP.app 的代码签名

c# - 单击时如何将文本从 <li> 传递到文本框?

c# - 如何在 asp.net c# treeview 控件中绑定(bind)数据

c# - List<string> 中 StartsWith 和 Contains 的使用?

使用 Xamarin 的 Azure 移动应用程序身份验证

xaml - 在 Xamarin XAML 中,如何使用样式在relativelayout上设置约束?

android - Xamarin - Visual Studio - 尽管已安装,但 Android 编译版本不存在

android - Grid.RowDefinitions Height 属性不适用于 Xamarin.Forms 中的固定值或 Auto