我已经在我的应用中创建了一个IncrementalLoadingCollection
类,它实现了ISupportIncrementalLoading
并继承自ObservableCollection< T >
。
它工作正常并且项目已加载但我想在应用程序的Status Bar
上显示一条消息,表明正在进行一些工作。
实现这一目标的好方法是什么?
由于在滚动列表时会在内部调用LoadMoreItemsAsync
,因此我无法访问该部分以提供更新Status Bar
的代码。现在,我在LoadMoreItemsAsync
这样做,我发现这是一个糟糕的方法,但到目前为止我找不到更好的...
非常感谢任何建议。
答案 0 :(得分:4)
嗯,你可以举例:从ObservableCollection
继承并实现ISupportIncrementalLoading
,如下所示:
class IncrementalLoadingObservableCollection<T> : ObservableCollection<T>, ISupportIncrementalLoading
{
private readonly Func<CancellationToken, Task<IEnumerable<T>>> _provideMoreItems;
public IncrementalLoadingObservableCollection(Func<CancellationToken, Task<IEnumerable<T>> provideMoreItems)
{
_provideMoreItems = provideMoreItems;
}
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
return AsyncInfo.Run(async cancelToken =>
{
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
OnLoadMoreItemsStarted();
});
var providedItems = await _provideMoreItems(cancelToken);
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
foreach(var item in providedItems)
Add(item);
OnLoadMoreItemsCompleted();
});
return new LoadMoreItemsResult {Count = (uint) providedItems.Count()};;
});
}
public bool HasMoreItems
{
get { return true; }
}
public event Action LoadMoreItemsStarted;
public event Action LoadMoreItemsCompleted;
protected virtual void OnLoadMoreItemsStarted()
{
var handler = LoadMoreItemsStarted;
if (handler != null) handler();
}
protected virtual void OnLoadMoreItemsCompleted()
{
var handler = LoadMoreItemsCompleted;
if (handler != null) handler();
}
}
如何使用它?在您的ViewModel中:
class MyFancyItemsViewModel
{
public MyFancyItemsViewModel()
{
var incrementalObservablCollcetion = new IncrementalLoading...(GetItemsFromInternetOrSmth);
incrementalObservablCollcetion.LoadMoreItemsStarted += OnItemsLoadingStarted;
incrementalObservablCollcetion.LoadMoreItemsCompleted += OnItemsLoadingCompleted;
ItemsBindedInXaml = incrementalObservablCollcetion;
}
private Task<IEnumerable<Items>> GetItemsFromInternetOrSmth(CancellationToken cancelToken)
{
... do some work returns enumerable of Items
}
private void OnItemsLoadingStarted()
{ .. do smth .. }
private void OnItemsLoadingCompleted()
{ ... do smth .. }
public ObservableCollection<Items> ItemsBindedInXaml { get; private set; }
}
你可能会问为什么我在Dispatcher.RunAsync
中使用了IncrementalLoadingObservableCollection
- 原因是LoadMoreItemsAsync
可能会在另一个主题上运行(不知道),所以你必须发送UI Thread
的所有工作(不能使用UI thread
以外的线程调用与UI相关的方法,而不使用Dispatcher
。)
如果您认为ViewModel
不适合与UI相关的操作,请查看一些消息传递机制(如MVVM Light Messenger
),在代码隐藏中注册消息并在{{1}中发送此消息处理程序)