0

I have a problem where im trying to use a Telerik Jump List with DataVirtualizationMode.Automatic, but i can't get it to work. The reason why i want to use this, is because i want my app to only download the data(games) which is in the current view of the Jump List control and not the whole data everytime. For example if i have searched for "Batman", and its returning 50 games, i don't want it to download and load all the games, only those i can see in the Jump List control.

Here is a sample of using DataVirtualizationMode.Automatic from Telerik, but i couldn't get it to work with my app: http://www.telerik.com/help/windows-phone/raddataboundlistbox-features-datavirtualization-automatic.html

Below is my Jump List control which i want to use with data virtualization.

MainPage.xaml:

<phone:PivotItem Header="Browse">
            <Grid>
                <telerikPrimitives:RadTextBox Name="txtSearch" HorizontalAlignment="Left" VerticalAlignment="Top" Height="80" Width="390"/>
                <telerikPrimitives:RadImageButton Name="imgBtnSeachGame" VerticalAlignment="Top" HorizontalAlignment="Right" ButtonShape="Ellipse" BorderThickness="2" Margin="0,8,0,0" Click="imgBtnSeachGame_Click"></telerikPrimitives:RadImageButton>

                <Controls:RadJumpList Name="jlGameList" ItemsSource="{Binding}" Tap="jlGameList_Tap" Margin="0,90,0,0" DataVirtualizationMode="Automatic">
                    <Controls:RadJumpList.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"></RowDefinition>
                                    <RowDefinition Height="*"></RowDefinition>
                                    <RowDefinition Height="20"></RowDefinition>
                                </Grid.RowDefinitions>
                                <Border Grid.Row="0" Background="{StaticResource PhoneAccentBrush}" 
        Padding="{StaticResource PhoneTouchTargetOverhang}"
        Margin="0,0,0,0">
                                    <TextBlock Name="tblGameTitle" Style="{StaticResource PhoneTextGroupHeaderStyle}" ManipulationStarted="tblGameTitle_ManipulationStarted" ManipulationCompleted="tblGameTitle_ManipulationCompleted">
                                        <Run Text="{Binding GameTitle}"></Run>
                                    </TextBlock>
                                </Border>
                                <Grid Background="#242424" Grid.Row="1">
                                    <Image Name="imgGameList" Margin="0,0,0,0" Stretch="Fill" HorizontalAlignment="Left" VerticalAlignment="Top" Height="96" Width="96">
                                        <Image.Source>
                                            <BitmapImage UriSource="{Binding BoxArtFrontThumb}"
                                 CreateOptions="BackgroundCreation" DecodePixelHeight="96" DecodePixelWidth="96" />
                                        </Image.Source>
                                    </Image>
                                    <TextBlock Margin="110,0,0,0" Text="Platform" FontWeight="Bold" TextWrapping="Wrap" Foreground="YellowGreen" FontSize="{StaticResource PhoneFontSizeNormal}"/>
                                    <TextBlock Name="txtPlatform" Margin="110,20,0,0" Text="{Binding Platform}"></TextBlock>

                                    <TextBlock Text="Release Date" FontWeight="Bold" Margin="110,46,0,0" Foreground="YellowGreen" FontSize="{StaticResource PhoneFontSizeNormal}"/>
                                    <TextBlock Name="txtReleaseDate" Margin="110,66,0,0" Text="{Binding ReleaseDate}"></TextBlock>
                                    <!--</StackPanel>-->
                                </Grid>
                                <Grid Grid.Row="2"></Grid>
                            </Grid>
                        </DataTemplate>
                    </Controls:RadJumpList.ItemTemplate>

                </Controls:RadJumpList>
            </Grid>
        </phone:PivotItem>

Below is where i bind my DataContext to my GetGamesListItems ObservableCollection in my GameData class. The imgBtnSearchGame_Click event method is being called when a user have typed for example "Batman" in my textbox txtSearch and tapped the button, it will then send the text to my GetGamesListData method.

MainPage.cs:

GameData gd = new GameData();

public MainPage()
    {
        InitializeComponent();
        jlGameList.DataContext = gd.GetGamesListItems;
    }

 private void imgBtnSeachGame_Click(object sender, RoutedEventArgs e)
    {
        if (!string.IsNullOrEmpty(txtSearch.Text))
        {
            gd.GetGamesListData(txtSearch.Text, "", "");
        }
    }

Below is where i download the data in XML for the game name searched for. For example if it is "Batman" it will find and return all games with "Batman". The "BoxArtFrontThumb" Property is where im storing all the images for each game and is using async, because sometimes there can be quite alot of images it has to download and show.

GameData.cs

public void GetGamesListData(string name, string platform, string genre)
    {
        var webClient = new WebClient();
        webClient.DownloadStringCompleted += GetGamesListRequestCompleted;
        webClient.DownloadStringAsync(new Uri("http://thegamesdb.net/api/GetGamesList.php?name=" + name));
    }

    private async void GetGamesListRequestCompleted(object sender, DownloadStringCompletedEventArgs e)
    {

        if (e.Error == null)
        {
            GetGamesListItems.Clear();
            var feedXml = XDocument.Parse(e.Result);
            var gameDataTasks = feedXml.Root.Descendants("Game").Select(
                async x => new GetGamesList
                {
                    ID = (int)x.Element("id"),
                    GameTitle = (string)x.Element("GameTitle"),
                    ReleaseDate = (string)x.Element("ReleaseDate") ?? "N/A",
                    Platform = (string)x.Element("Platform") ?? "N/A",
                    BoxArtFrontThumb = new Uri(await GetBoxArtFrontThumbAsync((int)x.Element("id")), UriKind.RelativeOrAbsolute),
                }).ToList();
            var gameData = await Task.WhenAll(gameDataTasks);
            foreach (var item in gameData)
            {
                GetGamesListItems.Add(item);
            }
        }
    }

Below is where its finding and storing the images for the games.

public async Task<string> GetBoxArtFrontThumbAsync(int id)
    {
        var client = new HttpClient();
        var result = await client.GetStringAsync("http://thegamesdb.net/api/GetArt.php?id=" + id);
        var feedXml = XDocument.Parse(result);
        var gameData = feedXml.Root.Descendants("Images").Select(x => new GetArt
        {
            BoxArtFrontThumb = new Uri(GetBoxArtFrontThumb(x), UriKind.RelativeOrAbsolute),
        }).ToList();


        return gameData.Single().BoxArtFrontThumb.ToString();
    }

private static string GetBoxArtFrontThumb(XElement gameNode)
    {
        string data = "http://thegamesdb.net/banners/" + (string)gameNode.Descendants("boxart")
                               .FirstOrDefault(b => (string)b.Attribute("side") == "front");

        if (data == "http://thegamesdb.net/banners/")
        {
            data = "/NoImage.jpg";
        }

        return data;
    }

I really hope i explained this well enough and hope that there is someone that can help me solve this problem. Thanks.

Thunder
  • 117
  • 18
  • Quick Question: Do you have a Telerik license? You can submit a support ticket where you can attach the project and we can investigate it directly (link below). Reply with the ticket number and I'll investigate it now, worst case scenario, I'll have someone from the development team that built the JumpList will get back to you within 24 hours. Submit ticket here http://www.telerik.com/account/support-tickets/available-support-list.aspx – Lance McCarthy Jun 09 '14 at 14:32
  • Thanks, working on it now. – Lance McCarthy Jun 09 '14 at 15:28
  • The last answer is the correct one. In order for it to be virtual, you have to let the VirtualizingDataCollection object to the work for you instead of your "GetGamesListData" method. You pass in the total amount of items to get and what page size to use. This will show you how to use VirtualizingDataCollection http://www.telerik.com/help/windows-phone/raddataboundlistbox-features-virtualizingdatacollection.html – Lance McCarthy Jun 09 '14 at 15:45
  • Thanks. I will try and see if i can get it to work. – Thunder Jun 09 '14 at 15:57
  • Keep in mind that this is only UI virtualization, you still need to download all of the items for that collection for the list to virtualize. It seems you are looking for a way to get Jumplist to so the partial gets from the service for you, that isn't possible. You need to find a way to get that service to page the results so that you can do another get in the "LoadData" method. I am working on your sample now and will reply to the ticket with any further results. – Lance McCarthy Jun 09 '14 at 16:10
  • I see. Thank you very much for your time on helping, i really appreciate it :), as i have been stuck with this problem for a while. – Thunder Jun 09 '14 at 16:14
  • What you can do is research the Games service you are using. If they have a way to retrieve results in segments, then you can get this to work the way that you want it to. The best way to understand this is to do the sample you see in the tutorial from the link in my answer below. Notice the "StartFromIndex" method, that's how you can retrieve the next segment of the results. – Lance McCarthy Jun 09 '14 at 16:46
  • Okay, im using this API from the site thegamesdb.net : http://wiki.thegamesdb.net/index.php?title=API_Introduction. I tryed the ODATA example but i couldn't get it to work as im not using ODATA. – Thunder Jun 09 '14 at 17:37
  • Thanks for the link, unfortunately, I do not see a parameter to give you the ability to segment returned results :( There is only Name, Platform and Genre). – Lance McCarthy Jun 09 '14 at 18:15
  • Okay, so what you are saying is that its impossible for me to get this to work with Data Virtualization Automatic :(? – Thunder Jun 09 '14 at 18:38
  • Correct. Also, it's not really appropriate to have an infinite list style approach when using JumpList. instead you'd want a DataBoundListBox. The reason for this is because the user expects all the items to be in the list when they tap on a header, so you are doing the right thing by getting all the items at once :) – Lance McCarthy Jun 09 '14 at 19:01
  • Thanks again for you help :). Okay, well the reason why i tryed all this data virtualization was actually because of all the images my app has to download for each games(BoxArtFrontThumb Property in my code). Do you know how i can decrease the image sizes of the images or somehow reduce the download time of all the images?. – Thunder Jun 09 '14 at 19:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/55342/discussion-between-lance-mccarthy-and-thunder). – Lance McCarthy Jun 09 '14 at 20:17
  • I've rewritten it to be much faster when loading the images. See the chat thread for the DL link. – Lance McCarthy Jun 09 '14 at 21:28

1 Answers1

1

Although you are using JumpList, the mechanism for Virtualizing the data is the same as the DataBoundListBox. (You can find more information here in the DataBoundListBox docs. There is a good tutorial using an OData service.)

In order for the Automatic mode to work properly, you need to be using Telerik's VirtualizingDataCollection object and initialize it with the proper arguments (count and page size).

I don't see this in the code you have provided above, can you please open a support ticket so that I can investigate further? See my comment above for the link. Let me know the ticket number and I'll provide further assistance.

Lance McCarthy
  • 1,884
  • 1
  • 20
  • 40