c# - ISupportIncrementalLoading 在离开后不会停止

标签 c# xaml windows-phone-8 infinite-scroll

突然发现实现ISupportIncrementalLoading的集合有一个奇怪的行为。 假设我们有一个主页,其中 ISupportIncrementalLoading 集合绑定(bind)到 ListView。我们还有另一个可以导航到的页面。 导航到主页时,ISupportIncrementalLoading 开始加载项目,直到 ListView 认为足够为止。在 ListView 加载它需要的所有项目之前,我导航到新页面。 我的预期行为:ListView 停止加载新项目,因为页面现在不可见。 真实行为:ListView 继续无休止地加载项目,即使在离开页面后也是如此。直到获得 HasMore == false 才会停止。 有人能帮忙吗?这是绝对错误的行为。

附言

如果我在导航时,在 ViewModel 中将集合设置为 null,然后在返回时将其恢复——这似乎很有帮助,但我认为这太过分了。

这是我的基本 ISupportIncrementalLoading 集合的代码:

public abstract class BaseIncrementalSupportCollection<T> :IList<T>,IList,INotifyCollectionChanged, ISupportIncrementalLoading, INotifyPropertyChanged
{
    protected readonly List<T> storage;

    private bool isLoading;
    public bool IsLoading
    {
        get
        {
            return isLoading;
        }
        set
        {
            if (isLoading != value)
            {
                isLoading = value;
                RaisePropertyChanged();
            }
        }
    }

    public bool failed;

    public bool IsFailed
    {
        get { return failed; }
        set
        {
            if (failed != value)
            {
                failed = value;
                RaisePropertyChanged();
            }
        }
    }

    public bool IsEmpty
    {
        get { return !HasMoreItems && Count == 0; }
    }

    protected BaseIncrementalSupportCollection()
    {
        storage = new List<T>();
    }

    public virtual IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
    {
        return Task.Run(()=>LoadMoreItems(count)).AsAsyncOperation();
    }

    public abstract bool HasMoreItems { get; }


    private async Task<LoadMoreItemsResult> LoadMoreItems(uint count)
    {
        IsLoading = true;
        IsFailed = false;
        try
        {
            var items = await LoadMoreItemsOverride(count);
            if (items == null)
                return new LoadMoreItemsResult() {Count = 0};
            if (items.Count > 0)
            {
                var prevEmptyState = IsEmpty;
                foreach (var item in items)
                {
                    var currItem = item;
                    await DispatchHelper.RunOnUiIfNecessary(async () =>
                    {
                        storage.Add(currItem);
                        RaiseCollectionChanged(
                            new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, currItem,
                                storage.Count - 1));
                    });
                }
                if(prevEmptyState!=IsEmpty)
                    RaisePropertyChanged("IsEmpty");

            }
            return new LoadMoreItemsResult() {Count = (uint) items.Count};
        }
        catch (Exception e)
        {
            var aggregate = e as AggregateException;
            if (aggregate != null)
                e = aggregate.Flatten().InnerException;
            IsFailed = true;
            var handler = OnError;
            if (handler != null)
                DispatchHelper.RunOnUiIfNecessary(
                    () => handler(this, new IncrementallCollectionLoadErrorEventArgs(e)));
            return new LoadMoreItemsResult() {Count = 0};
        }
        finally
        {
            IsLoading = false;
        }

    }

    protected virtual void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (CollectionChanged != null)
            CollectionChanged(this, e);
    }

    protected abstract Task<IList<T>> LoadMoreItemsOverride(uint count);

    [NotifyPropertyChangedInvocator]
    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            DispatchHelper.RunOnUiIfNecessary(()=>handler(this, new PropertyChangedEventArgs(propertyName)));
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public event EventHandler<IncrementallCollectionLoadErrorEventArgs> OnError;
    public event NotifyCollectionChangedEventHandler CollectionChanged;
}

最佳答案

我刚刚找到另一种方法,添加额外的 bool 字段 isStopped 方法 Start,ForceStop 将其设置为 false/true。在获取 HasMoreItems 时使用此值,例如

bool HasMoreItems{get{return !isStopped && DetermineIfHasMore()};}

只需调用这些方法,我就可以停止或继续加载同一个集合生成器。

这里提供了另一种方式https://social.msdn.microsoft.com/Forums/ru-RU/be17357d-faac-4f49-acf4-e916fcdace9d/w81isupportincrementalloading-doesnt-stop-after-navigating-away?forum=winappswithcsharp

关于c# - ISupportIncrementalLoading 在离开后不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30000061/

相关文章:

windows-phone-8 - c#中的facebook loginbutton sdk崩溃应用程序

c# - ''(过程)的请求失败”,因为它是一个表对象 - 错误

silverlight - 是否在 XAML 上分配指向其代码隐藏类的 DataContext

c# - 将列表或数组从 Arden MLM 传递到 C#

wpf - 如何更改按钮上 TextBlock 的文本?

c# - WPF ListView : Detect when listviewitem is selected and then check it

javascript - 第二个 ajax 调用在 Phonegap Jquery 移动 Windows 手机 8 中不起作用

wpf - 绑定(bind)到父数据上下文(超出 itemssource)

javascript - 使用 javascript 或 jquery 计算持续时间

C# XSLT : How to debug this error?