ISupportIncrementalLoading

ISupportIncrementalLoading

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

聚苯乙烯

如果我在导航时,将ViewModel中的collection设置为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;
}

最佳答案

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

bool HasMoreItems {get {return!isStopped &&确定IfHasMore()};}

只需将这些方法调用即可,我可以停止或继续加载相同的集合生成器。

此处提供了另一种方法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/

10-12 04:51