VirtualQueryableCollectionView& FilterDescriptor

10 posts, 0 answers
  1. ATeam
    ATeam avatar
    24 posts
    Member since:
    Jan 2010

    Posted 03 Jul 2012 Link to this post

    Hello,

    I have some trouble with the VirtualQueryableCollectionView and FilterDescriptors. If I add a FilterDescriptor to the VirtualQueryableCollectionView the ItemsLoading Event is never called. If I don't add the FilterDescriptor the ItemsLoading event is called.

    I have searched around the web, but I haven't found a solution or some information about why.

    In xaml code I have defined a RadComboBox

    <UserControl.Resources>
        <ResourceDictionary>
          <DataTemplate x:Key="cbPersonItemTemplate">
            <StackPanel>
              <TextBlock Text="{Binding Name}" />
            </StackPanel>
          </DataTemplate>
        </ResourceDictionary>
      </UserControl.Resources>
      <Grid x:Name="LayoutRoot" Background="White">
        <telerik:RadComboBox x:Name="cbPerson"
                     Text="{Binding Path=Text, Mode=TwoWay}"
                     ItemsSource="{Binding Path=CollectionView}"
                     ItemTemplate="{StaticResource cbPersonItemTemplate}"
                     IsEditable="True"
                     Width="200" Height="30"
                     VerticalAlignment="Top" HorizontalAlignment="Left">
          <telerik:RadComboBox.ItemsPanel>
            <ItemsPanelTemplate>
              <VirtualizingStackPanel />
            </ItemsPanelTemplate>
          </telerik:RadComboBox.ItemsPanel>
        </telerik:RadComboBox>         
      </Grid>

    The Codebehind of this xaml looks like this:
    public partial class PersonSelector : UserControl, INotifyPropertyChanged
    {
        public PersonSelector()
        {
            InitializeComponent();
     
            int personCount = 10000;
            //10000 Personen erzeugen
            Person.CreatePersons(personCount);
     
            collectionView = new VirtualQueryableCollectionView<Person>() { LoadSize = 10, VirtualItemCount = personCount };
     
            collectionView.FilterDescriptors.Add(new FilterDescriptor("SearchKey", FilterOperator.StartsWith, ""));
     
     
            collectionView.ItemsLoading += collectionView_ItemsLoading;
     
            cbPerson.DataContext = this;
        }
     
        private void collectionView_ItemsLoading(object sender, VirtualQueryableCollectionViewItemsLoadingEventArgs e)
        {
            var searchKey = String.Empty;
     
            if (CollectionView.FilterDescriptors.Count > 0)
                searchKey = (CollectionView.FilterDescriptors[0] as FilterDescriptor).Value.ToString();
            else
                searchKey = Text;    
     
            var pList = Person.GetPersons(searchKey, e.StartIndex, e.ItemCount);
     
            CollectionView.Load(e.StartIndex, pList);
        }
     
        private VirtualQueryableCollectionView collectionView;
        public virtual VirtualQueryableCollectionView CollectionView
        {
            get { return collectionView; }
            set
            {
                collectionView = value;
                DoPropertyChanged("CollectionView");
            }           
        }
     
        private string text;
        public string Text
        {
            get { return text; }
            set
            {
                if (text  != value)
                {
                    text = value;                  
                    if (CollectionView.FilterDescriptors.Count > 0)
                        (CollectionView.FilterDescriptors[0] as FilterDescriptor).Value = text;                   
                    DoPropertyChanged("Text");
                }
            }
        }
     
        #region INotifyPropertyChanged Members
     
        public virtual event PropertyChangedEventHandler PropertyChanged;
     
        public virtual void DoPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
         
        #endregion INotifyPropertyChanged Members
    }

    I am little bit confused, why the ItemsLoading event is not fired, if I had added a FilterDescriptor. The reason is that I don't want to load all entries at one time, it should have a behavour like loading on demand. First 10 entries, if the user scrolls down in the combobox the next 10, and so on, filtered by the text the user has entered in the input area of the combobox.

    Has anyone an idea, what I have to change to get this working?



  2. Yordanka
    Admin
    Yordanka avatar
    634 posts

    Posted 05 Jul 2012 Link to this post

    Hi Dominik,

    Basically, the idea behind VirtualQuaryableCollectionView is exactly the same as that you want to achieve. The combobox will load as many items as specified from LoadSize - in your case 10. When the combobox is scrolled ItemsLoading event will be called and the next 10 items will be loaded. Same will occur for each scrolling. This behavior will happen whether or not a filter descriptor is used.

    However, in your code there is additional calling of Load method which breaks the logic and loads the items again:

    private void collectionView_ItemsLoading(object sender, VirtualQueryableCollectionViewItemsLoadingEventArgs e)
        {
            ...
            CollectionView.Load(e.StartIndex, pList);
        }

    Removing the highlighted line will resolve the problem. 
     
    Kind regards,
    Yordanka
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. DevCraft banner
  4. ATeam
    ATeam avatar
    24 posts
    Member since:
    Jan 2010

    Posted 05 Jul 2012 Link to this post

    Hello Yordanka,

    thank you for your reply.

    I tried out what you have told me, I have commented out the line where I told the collectionView which data it should take (I am not sure, how it should work without...).

    But there is no difference, if I add the Filterdescriptor the ItemsLoading Event method never get called. If I don't add the filterdescriptor to the VirtualQueryableCollectionView the ItemsLoading event is called. In the case without the Filterdescriptor added and included your idea for not calling Load the Combobox keeps empty. The only thing is, that I got 10000 empty rows (the loading is called,even if I don't scroll ... by opening the dropdown all the event is called until all items loaded (but not into the view, cause the load method is not called, cause you told me for not calling Load).

    Something went wrong and sadly I can't see what.
  5. Yordanka
    Admin
    Yordanka avatar
    634 posts

    Posted 05 Jul 2012 Link to this post

    Hello Dominik,

    I am sending you my test project. Let me know if you have any questions.
     
    Regards,
    Yordanka
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  6. ATeam
    ATeam avatar
    24 posts
    Member since:
    Jan 2010

    Posted 05 Jul 2012 Link to this post

    Hello Yordanka,

    thank you for your sample. It's correct that in your sample calling Load would load the data twice...

    There is a little difference, but I think an important one. In your sample you create the VirtualQueryableCollectionView like this:

    this.collectionView = new VirtualQueryableCollectionView(Player.GetPlayers()) { LoadSize = 10, VirtualItemCount = 10000 };

    But I have created it like this:
    collectionView = new VirtualQueryableCollectionView<Person>() { LoadSize = 10, VirtualItemCount = personCount };

    The thing I have posted is only a little sample... the real data should come over a web service. I think that explains why I think that I have to call the Load method in ItemsLoading event.
  7. Ryan
    Ryan avatar
    7 posts
    Member since:
    Jun 2012

    Posted 07 Jul 2012 Link to this post

    Once i was stuk in

    VirtualQueryableCollectionView thanks to telerik forum which solved my issue.


    public
     VirtualQueryableCollectionView VirtualEventsList
            {
                get
                {
                    if (_VirtualEventsList == null)
                    {
                        _VirtualEventsList = new VirtualQueryableCollectionView() { LoadSize = 50, VirtualItemCount = 1 };
     
                        _VirtualEventsList.FilterDescriptors.Clear();
                        _VirtualEventsList.FilterDescriptors.Add(_QuickSearchFilterDescriptor);
     
                        _VirtualEventsList.ItemsLoading += (s, e) =>
                        {
                            EventListIsBusy = true;
                            var query = Context.GetEventsQuery(GetSelectedPositions());
     
                            var queryToLoad = query
                                .IncludeTotalCount(true)
                                .Sort(_VirtualEventsList.SortDescriptors)
                                .Where(_VirtualEventsList.FilterDescriptors)
                                .Skip(e.StartIndex)
                                .Take(e.ItemCount);
     
                            Context.Load<Event>(queryToLoad).Completed += (sender, args) =>
                            {
                                var lo = (LoadOperation)sender;
                                if (lo.TotalEntityCount != -1 && lo.TotalEntityCount != _VirtualEventsList.VirtualItemCount)
                                {
                                    _VirtualEventsList.VirtualItemCount = lo.TotalEntityCount;
                                }
     
                                _VirtualEventsList.Load(e.StartIndex, lo.Entities);
                                EventListIsBusy = false;
                            };
                        };
     
                    }
                    return _VirtualEventsList;
                }           
  8. ATeam
    ATeam avatar
    24 posts
    Member since:
    Jan 2010

    Posted 09 Jul 2012 Link to this post

    Hello Ryan,

    thank you for your answer, but this does not solve my problem.

    I still have the problem, that I want to load the data on demand (when the user scrolls down in the RadComboBox). Every time I add a Filterdescriptor the Itemsloading event is not called. It makes no difference if I first clear the FilterDescriptorcollection.

    I tried additionally putting some SortDescriptors into to SortDescriptorcollection and removing it, to motivate the CollectionView calling the ItemsLoading event, but it does not helped.

    So I am still looking for a solution for my problem.
  9. Bart
    Bart avatar
    2 posts
    Member since:
    Sep 2012

    Posted 04 Apr 2013 Link to this post

    Hello Dominik

    Did you eventually solve your problem? I have the exact same problem in my project now.

    I recently upgraded my Telerik controls to Q3 2012 SP1 and adding a Filterdescriptor to a VirtualQueryableCollectionView doesn't call the Itemsloading event so my gridview is empty. Before, when I was using Q2 2012 SP2, I had no problems when adding Filterdescriptors.

    Regards
  10. Yordanka
    Admin
    Yordanka avatar
    634 posts

    Posted 08 Apr 2013 Link to this post

    Hi Bart,

    I've checked DataVirtualization FirstLook demo and everything works as expected. Please give it a try and let us know about the result on your end. 
     
    All the best,
    Yordanka
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  11. Bart
    Bart avatar
    2 posts
    Member since:
    Sep 2012

    Posted 08 Apr 2013 Link to this post

    Hi Yordanka

    After upgrading my Telerik controls to the latest version, the problem was solved. Thanks anyway:)

    Regards
    Bart
Back to Top
DevCraft banner