【问题标题】:What is the best practice for using ISupportIncrementalLoading in MVVM?在 MVVM 中使用 ISupportIncrementalLoading 的最佳实践是什么?
【发布时间】:2016-05-12 13:14:14
【问题描述】:

这听起来很奇怪,我知道使用 ISupportIncrementalLoading 是用于 MVVM 的视图层。

现在,每当 ViewModel 中的集合属性更新时,我都会在 xaml.cs 中刷新我的 ListView 的 itemssource。对于这种需求,还有其他(更好的)解决方案吗?

【问题讨论】:

    标签: listview mvvm scroll win-universal-app prism


    【解决方案1】:

    您好,我已经多次使用 MVVM 模式使用 ISupportIncrementalLoading。

    我喜欢创建一个独立的类来封装所有逻辑以加载所有数据我在这里放一个我的一个类的示例我希望这会有所帮助。

    我创建了一个 IncrementalCollectionBase 来重用我所有自定义集合中的所有代码。

      public class IncrementalCollectionBase<T> : ObservableCollection<T>,
        ISupportIncrementalLoading,
        INotifyPropertyChanged,
        IIncrementalCollection<T>, IDisposable
    {
        private long totalRecordCount;
    
    
    
        public int PageNo { get; set; }
        public int PageSize { get; set; }
        public int PageCount { get; set; }
        public long TotalRecordCount
        {
            get
            {
                return this.totalRecordCount;
            }
    
            set
            {
                this.totalRecordCount = value;
                OnPropertyChanged(new PropertyChangedEventArgs("TotalRecordCount"));
            }
        }
    
        public IncrementalCollectionBase()
        {
            this.FeedSize = 10;
        }
        public CancellationTokenSource CancelToken { get; set; }
    
    
        public bool HasMoreItems { get; set; }
    
    
        private bool isLoading { get; set; }
        public bool IsLoading
        {
            get
            {
                return isLoading;
            }
    
            set
            {
                isLoading = value;
                OnPropertyChanged(new PropertyChangedEventArgs("IsLoading"));
    
            }
        }
    
        public int FeedSize { get; set; }
    
        public event EventHandler<LoadIncrementalCollectionChanged> OnLoadIncrementalCollectionChanged;
    
        public void Cancel()
        {
            try
            {
                CancelToken?.Cancel();
            }
            catch (Exception ex)
            {
    
    
            }
        }
    
        public virtual Task<IEnumerable<T>> LoadDataAsync()
        {
            throw new NotImplementedException();
        }
    
        public virtual IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            throw new NotImplementedException();
        }
    
        public virtual void Setup(CancellationTokenSource cancelToken = null)
        {
    
            CancelToken = cancelToken;
        }
    
        public void Dispose()
        {
            try
            {
                Cancel();
                Items.Clear();
            }
            catch (Exception)
            {
    
    
            }
        }
    }
    

    完成此操作后,我创建了我的自定义集合

        public class MyCustomEntityIncrementalCollection : IncrementalCollectionBase<CustomEntity>
    {
    
        private ISearchentityService searchentityService = null;
        private bool searchMode = false;
        private string key = "";
        private bool IsFirstSearchResult = true;
        private IentityService entityService = null;
        private ILoginService loginService = null;
        private IToastService toastService = null;
        public MyCustomEntityIncrementalCollection(CancellationTokenSource cancelToken, int feedSize = 10)
        {
            Setup(cancelToken);
            this.FeedSize = feedSize;
            toastService = IoC.Get<IToastService>();
            searchentityService = IoC.Get<ISearchentityService>();
            loginService = IoC.Get<ILoginService>();
            entityService = IoC.Get<IentityService>();
        }
    
        private async Task<IEnumerable<CustomEntity>> Search()
        {
            try
            {
                if (IsFirstSearchResult)
                {
    
                    var result = await searchentityService.SearchAsync(key, loginService.CurrentUser.Id, CancelToken, loginService.CurrentToken.AccessToken, 1, 50);
                    if (result == null)
                    {
                        toastService.ShowAsync("Sin resultados", "No se han encontrado coincidencias");
                    }
                    PageNo = result.paging.pageNo;
                    PageCount = result.paging.pageCount;
                    PageSize = result.paging.pageSize;
                    TotalRecordCount = result.paging.totalRecordCount;
                    IsFirstSearchResult = false;
                    return result.data;
                }
                else
                {
                    var result = await searchentityService.SearchAsync(key, loginService.CurrentUser.Id, CancelToken, loginService.CurrentToken.AccessToken, (PageNo + 1), 50);
                    PageNo = result.paging.pageNo;
                    PageCount = result.paging.pageCount;
                    PageSize = result.paging.pageSize;
                    TotalRecordCount = result.paging.totalRecordCount;
                    return result.data;
                }
            }
            catch (Exception)
            {
    
    
            }
            return null;
        }
    
        public async Task TurnOnSearchMode( string keyword)
        {
            if (string.IsNullOrEmpty(keyword) || string.IsNullOrWhiteSpace(keyword))
                throw new Exception(" keyword is invalid");
            searchMode = true;
            key = keyword;
            IsFirstSearchResult = true;
            this.ClearItems();
            await Task.Delay(500);
           await LoadMoreItemsAsync(1);
        }
        public async Task TurnOffSearchMode()
        {
    
           searchMode = false;
            IsFirstSearchResult = true;
            key = "";
            this.ClearItems();
            await LoadMoreItemsAsync(1);
        }
        public override async Task<IEnumerable<CustomEntity>> LoadDataAsync()
        {
            try
            {
                if (this.Items.Count == 0)
                {
                    var result = await entityService.MyEntities(CancelToken, loginService.CurrentToken.AccessToken, 1, FeedSize);
                    if (result != null && result.data != null)
                    {
                        PageNo = result.paging.pageNo;
                        PageCount = result.paging.pageCount;
                        PageSize = result.paging.pageSize;
                        TotalRecordCount = result.paging.totalRecordCount;
                        return result.data;
                    }
                }
                else
                {
                    var result = await entityService.MyEntities(CancelToken, loginService.CurrentToken.AccessToken, (PageNo + 1), FeedSize);
    
                    PageNo = result.paging.pageNo;
                    PageCount = result.paging.pageCount;
                    PageSize = result.paging.pageSize;
                    TotalRecordCount = result.paging.totalRecordCount;
                    return result.data;
                }
            }
            catch (Exception)
            {
    
    
            }
    
            return null;
        }
    
        public override IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            return AsyncInfo.Run(async c =>
            {
                await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, ( () =>
                {
                    IsLoading = true;
                }));
    
                if (searchMode == false)
                {
                    try
                    {
                        var data = await LoadDataAsync();
                        if (data != null && data.Any())
                        {
    
                            HasMoreItems = true;
                        }
                        else
                        {
                            HasMoreItems = false;
                        }
    
                        if (data != null)
                        {
                            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, (() =>
                            {
    
                                foreach (var item in data)
                                {
    
                                    this.Add(item);
                                }
                            })).AsTask().ContinueWith(z => { data = null; });
    
                        }
    
                    }
                    catch (Exception ex)
                    {
    
                        Debug.WriteLine("Se ha producido un error al buscar videos");
                    }
                }
    
                else
                {
                    try
                    {
                        var data = await Search();
                        if (data != null && data.Any())
                        {
    
                            HasMoreItems = true;
                        }
                        else
                        {
                            HasMoreItems = false;
                        }
    
                        if (data != null)
                        {
                            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, (() =>
                            {
    
                                foreach (var item in data)
                                {
    
                                    this.Add(item);
                                }
                            })).AsTask().ContinueWith(z => { data = null; });
    
                        }
    
                    }
                    catch (Exception ex)
                    {
    
                        Debug.WriteLine("Se ha producido un error al buscar videos");
                    }
                }
    
                await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, ( () =>
                {
                    IsLoading = false;
                }));
                return new LoadMoreItemsResult() { Count = count };
            });
    
        }
    
    
    }
    

    最后我只是在构造函数或其他地方调用我的视图模型中的初始加载。

     this.MyEntities = new Infrastructure.Collections.MyCustomEntityAppraisalIncrementalCollection(cancelToken, 20);
    
    await MyEntities.LoadMoreItemsAsync(1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-20
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2011-06-07
      相关资源
      最近更新 更多