那麼你可以,例如:從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();
}
}
如何使用它?在您的視圖模型:
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; }
}
你可能會問,爲什麼我在IncrementalLoadingObservableCollection
使用Dispatcher.RunAsync
- 原因是LoadMoreItemsAsync
可能在另一個線程上運行(不知道),所以你必須派遣所有的工作到UI Thread
(如果不使用Dispatcher
,則不可能從UI thread
以外的線程調用與UI相關的方法)。
如果你覺得ViewModel
不appropiate地方UI相關的操作看一看一些通訊機制(如MVVM Light Messenger
,註冊代碼隱藏消息,並在LoadMoreItemsStarted
處理程序發送該消息)
來源
2015-01-09 22:37:36
fex
使用這種方法事件絕對是偉大的,我喜歡它!我已經在使用調度員回覆UI的消息,但由於可怕的耦合,我完全不滿意。如果只有我可以多次投票這個答案:)非常感謝! – VasileF 2015-01-09 23:22:38
似乎雖然通知只發生一次,在第一個電話...我已經做了一個編輯。處理程序中的代碼是在斷點被執行時執行的,但UI上沒有顯示任何內容...... – VasileF 2015-01-09 23:48:01
@VasileF與IncrementalObservableCollection無關錯誤 - 調用OnCompleted時調用「StatusBar.HideAsync」(根據您的代碼)這意味着StatusBar將被關閉,直到您調用「StatusBar.ShowAsync」。所以你需要調用:await statusBar.ShowAsync();在顯示進度指示器 – fex 2015-01-09 23:55:35