티스토리 뷰

반응형

Windows 8부터 대용량의 데이터를 한번에 조회를 하지 않고, 스크롤이 될때 조금씩 계속 조회하는 것을 지원한다. 그에 대한 예제를 MSDN에서 찾아 볼 수 있는데..좀 복잡하게 되어 있어서 이해하기가 쉽지 않아서 간단한 예제를 만들어 보았다. 기존에 작성되었던 WebAPI Sample 프로젝트에 기능을 추가했다.

 

1. 참고

ISupportIncrementalLoading interface

http://msdn.microsoft.com/en-us/library/windows/apps/Hh701916

 

Data virtualization example using ISupportIncrementalLoading

http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/8f7a1a5b-6a8d-4971-8f38-2075295298b5/

 

 왼쪽 리스트박스에 데이터가 스크롤 될 때 조금씩 조회되는 형태이다.

 

2. PersonILCollection.cs

 

    public class PersonILCollection : ObservableCollection<Person>, ISupportIncrementalLoading
    {
        private const string ApiRoot = "http://localhost:11666//api/person?$orderby=Id&$skip={0}&$top={1}";
        private int page;
        private bool _busy;

        #region ISupportIncrementalLoading
        public bool HasMoreItems
        {
            get { return true; }
        }

        public Windows.Foundation.IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            if (_busy)
            {
                return null;
            }
            _busy = true;

            return AsyncInfo.Run((c) => LoadMoreItemsAsync(c, count));
        }
        #endregion

        /// <summary>
        /// 점진적 조회 구현, 참고용이니 새롭게 구현하기 바람
        /// </summary>
        /// <param name="c"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        async Task<LoadMoreItemsResult> LoadMoreItemsAsync(CancellationToken c, uint count)
        {
            try
            {
                ObservableCollection<Person> items = new ObservableCollection<Person>();

                //http 설정
                using (var http = new HttpClient())
                {
                    //전체 데이터 조회
                    var size = 10;
                    var skip = (page - 1) * size;
                    var getQuery = string.Format(ApiRoot, skip, size);

                    var resp = await http.GetStringAsync(getQuery);
                    if (resp != null)
                    {
                        items = JsonConvert.DeserializeObject(resp, typeof(ObservableCollection<Person>)) as ObservableCollection<Person>;
                        //컬렉션에 데이터 추가
                        foreach (var i in items)
                        {
                            this.Add(i);
                        }

                        //페이지 카운터 증가
                        page++;
                    }
                }

                return new LoadMoreItemsResult { Count = (uint)items.Count() };
            }
            finally
            {
                _busy = false;
            }
        }

        /// <summary>
        /// 생성자
        /// </summary>
        public PersonILCollection()
        {
            page = 1;
        }
    }

 

3. MainPageView.xaml

 

        <ListView Grid.Row="2" ItemsSource="{Binding PeopleILC}"
                  ItemTemplate="{StaticResource PersonDataTemplate}" Padding="120,0,0,0"/>

 

4. MainPageViewModel.cs

생성자에서 초기화 시킴

 

        private PersonILCollection peopleILC;

        public PersonILCollection PeopleILC
        {
            get { return peopleILC; }
            set
            {
                peopleILC = value;
                OnPropertyChanged();
            }
        }

 

5. 기본 원리

ISupportIncrementalLoading를 상속 받은 컬렉션을 ListView, GridView에 바인딩 시키면 각 컨트롤에서 데이터가 필요하다고 생각이 되면 LoadMoreItemsAsync 이벤트가 발생이 되고, 이때 필요한 데이터를 로딩하면 된다.

(IncrementalLoadingTrigger, IncrementalLoadingThreshold 프로퍼티가 존재하는 컨트롤은 지원이 된다.)

 

6. 소스

W8RTM_c#_ISupportIncrementalLoading_sample.zip

 

http://sdrv.ms/14WaiAf

 

 

반응형
댓글