This is a migrated thread and some comments may be shown as answers.

VirtualQueryableCollectionView& FilterDescriptor

9 Answers 204 Views
Data Virtualization
This is a migrated thread and some comments may be shown as answers.
ATeam
Top achievements
Rank 1
ATeam asked on 03 Jul 2012, 03:23 PM
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?



9 Answers, 1 is accepted

Sort by
0
Yordanka
Telerik team
answered on 05 Jul 2012, 09:16 AM
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 >>

0
ATeam
Top achievements
Rank 1
answered on 05 Jul 2012, 11:30 AM
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.
0
Yordanka
Telerik team
answered on 05 Jul 2012, 11:44 AM
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 >>

0
ATeam
Top achievements
Rank 1
answered on 05 Jul 2012, 11:58 AM
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.
0
Ryan
Top achievements
Rank 1
answered on 07 Jul 2012, 09:36 AM
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;
            }           
0
ATeam
Top achievements
Rank 1
answered on 09 Jul 2012, 07:29 AM
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.
0
Bart
Top achievements
Rank 1
answered on 04 Apr 2013, 02:51 PM
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
0
Yordanka
Telerik team
answered on 08 Apr 2013, 12:15 PM
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.

0
Bart
Top achievements
Rank 1
answered on 08 Apr 2013, 12:19 PM
Hi Yordanka

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

Regards
Bart
Tags
Data Virtualization
Asked by
ATeam
Top achievements
Rank 1
Answers by
Yordanka
Telerik team
ATeam
Top achievements
Rank 1
Ryan
Top achievements
Rank 1
Bart
Top achievements
Rank 1
Share this question
or