2015-01-09 3 views
1

ISupportIncrementalLoading을 구현하고 ObservableCollection< T >에서 상속받은 IncrementalLoadingCollection 클래스를 내 앱에 생성했습니다.ISupportIncrementalLoading Collection - LoadingMoreItems가 진행 중일 때 UI에 알립니다.

잘 작동하고 항목이로드되었지만 앱의 Status Bar에 진행중인 작업이 있다는 메시지를 표시하고 싶습니다.

이것을 달성하는 좋은 방법은 무엇입니까?

LoadMoreItemsAsync은 목록 스크롤시 내부적으로 호출되므로 해당 부분에 액세스하여 Status Bar을 업데이트하는 코드를 찾을 수 없습니다. 바로 지금, 나는 이것을 끔찍한 접근법이라고 생각하는 LoadMoreItemsAsync에서 이것을하고 있습니다. 그러나 나는 지금까지 더 좋은 방법을 찾을 수 없었습니다 ...

어떤 제안이라도 매우 높이 평가됩니다.

답변

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에 : 나는 IncrementalLoadingObservableCollectionDispatcher.RunAsync을 사용하는 이유

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; } 
} 

당신은 요청할 수 있습니다 - 이유는 LoadMoreItemsAsync 다른 스레드에서 실행할 수 있다는 것입니다 (모르겠어요) 그래서 당신은 UI Thread에 모든 작업을 파견해야 (Dispatcher을 사용하지 않고 UI thread 이외의 스레드에서 UI 관련 메서드를 호출 할 수 없습니다. 당신이 UI 관련 작업이

+1

사용이 방식을 (MVVM Light Messenger 같은 코드 숨김에서 메시지를 등록하고 LoadMoreItemsStarted 핸들러에서이 메시지를 보내) 일부 메시징 메커니즘에 대해 살펴 위해 ViewModel가 appropiate 장소 아니라고 판단되는 경우

이벤트는 절대적으로 훌륭합니다. 디스패처를 사용하여 메시지가있는 UI로 되돌아 갔지만 끔찍한 결합 때문에 전혀 만족스럽지 않았습니다. 이 답변을 여러 번 투표 할 수만 있다면 :) 고마워요! – VasileF

+0

알림은 첫 번째 호출에서 한 번만 발생하지만 ... 편집을 완료 한 것으로 보입니다. 중단 점이 적중 될 때 처리기의 코드가 실행되지만 UI에 아무 것도 표시되지 않습니다. – VasileF

+0

IncrementalObservableCollection과 관련된 오류가 아닌 @VasileF - OnCompleted가 호출 될 때 "StatusBar.HideAsync"가 호출됩니다 (코드에 따라) 즉 StatusBar는 "StatusBar.ShowAsync"를 호출 할 때까지 닫힙니다. 그래서 호출해야합니다 : await statusBar.ShowAsync(); 진행 표시기를 표시하기 전에 – fex