我突然发现实现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/