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

ComboBox not loading items using VirtualQueryableCollectionView

3 Answers 83 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
barak
Top achievements
Rank 1
barak asked on 21 Nov 2011, 03:08 PM
We have an issue in which a RadComboBox configured with VirtualizingStackPanel
and using an ItemsSource of VirtualQueryableCollectionView, sometimes doesn't load items, especially when scrolling to the end of it.

For example, when the combo-box drop-down is opened and initial items are loaded,
If you scroll straight to the end of the combo-box using the vertical scroll-bar,
the ItemLoading event won't be triggered in the VirtualQueryableCollectionView that uses as the ItemsSource.
The scenario is when loading items async (without RIA).


Telerik documentation declare the RadComboBox suppose to work with VirtualQueryableCollectionView
http://www.telerik.com/help/silverlight/using-data-virtualization.html

So my question is, is it RadComboBox / VirtualQueryableCollectionView issue or
is it incorrectly practicing the data virtualization (as shown in the attached sample)?

Thanks

-Attached is a sample that demonstrate the problem-

--The View--
<UserControl>
x:Class="Telerik.Windows.Examples.ComboBox.DataVirtualization.Example"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:local="clr-namespace:Telerik.Windows.Examples.ComboBox.DataVirtualization" mc:Ignorable="d"

d:DesignHeight="800" d:DesignWidth="600"
>
<
UserControl.Resources>
        <
local:BindingFallbackHelperConverter x:Key="BindingFallbackHelperConverter" Value="Visible" />

        <DataTemplate x:Key="DataItemTemplate" >
            <
Grid>
                <
Grid.ColumnDefinitions>
                    <
ColumnDefinition Width="100" />
                    <
ColumnDefinition Width="100" />
                </
Grid.ColumnDefinitions>
                <
TextBlock Text="{Binding Text}" Margin="0,0,10,0" />
                <
ProgressBar Grid.Column="1" Minimum="0" Maximum="100" Value="{Binding Score}"
                             Visibility="{Binding Score, Converter={StaticResource BindingFallbackHelperConverter}, FallbackValue=Collapsed}"/>

            </
Grid>
        </
DataTemplate>
    </
UserControl.Resources>
    <
Grid>
        <
telerik:RadComboBox Grid.Row="1" Width="250" VerticalAlignment="Top" x:Name="RadComboBox"
                ClearSelectionButtonVisibility="Visible" ClearSelectionButtonContent="Clear selection!"

                ItemsSource="{Binding Items}"  SelectedValuePath="Id" IsEditable="False" IsFilteringEnabled="False"

                IsTextSearchEnabled="False" ItemTemplate="{StaticResource DataItemTemplate}">

            <
telerik:RadComboBox.ItemsPanel>
                <
ItemsPanelTemplate>
                    <
VirtualizingStackPanel />
                </
ItemsPanelTemplate>
            </
telerik:RadComboBox.ItemsPanel>
        </
telerik:RadComboBox>
    </
Grid>
</
UserControl>


public partial class Example : UserControl
{
    public Example()
    {
        InitializeComponent();
        DataContext = new ExampleViewModel();
    }
}



public class BindingFallbackHelperConverter: IValueConverter
{
    public object Value { get; set; }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Value;
    }
     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The view-model
public class ExampleViewModel : ViewModelBase
{
    private VirtualQueryableCollectionView _Items;
    private ItemsDataLoader _ItemsDataloader;
 
    public ExampleViewModel()
    {
        _Items = new VirtualQueryableCollectionView()
        {
            LoadSize = 20,
            VirtualItemCount = 1000
        };
        _Items.ItemsLoading += OnItemsLoading;
 
        _ItemsDataloader = new ItemsDataLoader();
    }
 
    void OnItemsLoading(object sender, VirtualQueryableCollectionViewItemsLoadingEventArgs e)
    {
        if(DesignerProperties.IsInDesignTool) return;
        _ItemsDataloader.GetItemsAsync(e.StartIndex, e.ItemCount, OnGetItemsCompleted, e);
    }
 
    private void OnGetItemsCompleted(ItemsAsyncCallResult asyncCallResult)
    {
        var e = (VirtualQueryableCollectionViewItemsLoadingEventArgs) asyncCallResult.UserState;
        _Items.Load(e.StartIndex, asyncCallResult.Items);
    }
 
    public ICollectionView Items
    {
        get { return _Items; }
    }
}

The rest
public class DataItem: ViewModelBase
{
    private int _Id;
    private string _Text;
    private int _Score;
 
    public int Id
    {
        get { return _Id; }
        set
        {
            _Id = value;
            OnPropertyChanged(() => Id);
        }
    }
 
    public string Text
    {
        get { return _Text; }
        set
        {
            _Text = value;
            OnPropertyChanged(() => Text);
        }
    }
 
    public int Score
    {
        get { return _Score; }
        set
        {
            _Score = value;
            OnPropertyChanged(() => Score);
        }
    }
 
    public bool Equals(DataItem other)
    {
        if(ReferenceEquals(null, other)) return false;
        if(ReferenceEquals(this, other)) return true;
        return other._Id == _Id;
    }
 
    public override bool Equals(object obj)
    {
        if(ReferenceEquals(null, obj)) return false;
        if(ReferenceEquals(this, obj)) return true;
        if(obj.GetType() != typeof(DataItem)) return false;
        return Equals((DataItem) obj);
    }
 
    public override int GetHashCode()
    {
        return _Id;
    }
 
    public override string ToString()
    {
        return Text + " (" + Score + ")";
    }
}

internal class ItemsAsyncCallResult
{
    public ItemsAsyncCallResult(IEnumerable<DataItem> items, object userState)
    {
        Items = items;
        UserState = userState;
    }
 
    public IEnumerable<DataItem> Items { get; private set; }
    public object UserState { get; set; }
}

internal class ItemsDataLoader
{
    public void GetItemsAsync(int startIndex, int itemCount, Action<ItemsAsyncCallResult> completionCallback, object userState)
    {
        var random = new Random();
        int delayMilliseconds = random.Next(10, 1000);
        AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(null); //remember the calling thread
        Timer timer = null;
        TimerCallback callback = delegate
        {
            OnTimerTriggered(timer, asyncOp, startIndex, itemCount, completionCallback, userState);
        };
        timer = new Timer(callback, null, delayMilliseconds, Timeout.Infinite);
    }
 
    private void OnTimerTriggered(Timer timer, AsyncOperation asyncOp, int startIndex, int itemCount, Action<ItemsAsyncCallResult> completionCallback, object userState)
    {
        timer.Dispose();
        IEnumerable<DataItem> items = LoadItems(startIndex, itemCount);
        var result = new ItemsAsyncCallResult(items, userState);
 
        SendOrPostCallback callbackOnOriginalThread = arg => completionCallback(result);
        asyncOp.PostOperationCompleted(callbackOnOriginalThread, null);
    }
 
    private IEnumerable<DataItem> LoadItems(int startIndex, int itemCount)
    {
        var items = new List<DataItem>();
        for(int index = startIndex; index < startIndex + itemCount; index++)
        {
            var item = new DataItem
            {
                Id = index + 1001,
                Score = (index % 101),
                Text = "Item No " + (index + 1)
            };
            items.Add(item);
        }
        return items;
    }
}


3 Answers, 1 is accepted

Sort by
0
Yordanka
Telerik team
answered on 22 Nov 2011, 04:18 PM
Hi Barak,

I have tried to reproduce the problem you report but to no avail. Here is the result of my tests. Am I doing something wrong or missing something specific that may cause the problem?
I am attaching the test solution based on the provided code.

Kind regards,
Yordanka
the Telerik team

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

0
barak
Top achievements
Rank 1
answered on 24 Nov 2011, 05:59 PM
After performing more tests, it seems it's happen if Silverlight 5 RC is installed
while it works under Silverlight 4.

Isn't it RadComboBox compatible with Silverlight 5?

Thanks
0
barak
Top achievements
Rank 1
answered on 24 Nov 2011, 06:00 PM
After performing more tests, it seems it's happen if Silverlight 5 RC is installed
while it works under Silverlight 4.

Isn't it RadComboBox compatible with Silverlight 5?

Thanks
Tags
ComboBox
Asked by
barak
Top achievements
Rank 1
Answers by
Yordanka
Telerik team
barak
Top achievements
Rank 1
Share this question
or