none
Grid application

    Question

  • Hi,

    I want to load the images which are in my hard disk to my application in a grid format....I am using Grid application but not getting how bind data to items list....

    Please Help me out....

    Friday, March 09, 2012 10:22 AM

Answers

  • Vinayak,

    We have an SDK Sample that might help you out. Check out the StorageDataSource and GetVirtualizedFilesVector Sample.

    The code below, copied right out of the C# version of the above SDK Sample, shows how you can create a FolderQuery and then get a Virtualized Vector that you can plug right into your GridView's ItemsSource.

    var library = Windows.Storage.KnownFolders.PicturesLibrary; var queryOptions = new Windows.Storage.Search.QueryOptions(); queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep; queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable; var fileQuery = library.CreateFileQueryWithOptions(queryOptions); var fif = new Windows.Storage.BulkAccess.FileInformationFactory( fileQuery, Windows.Storage.FileProperties.ThumbnailMode.PicturesView, 190, Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale, false ); var dataSource = fif.GetVirtualizedFilesVector();

    PicturesGrid.ItemsSource= dataSource;

    To get the file thumbnails to show up in your app, you will have to create a DataTemplate that uses the ThumbnailConverter ValueConverter class also included in the SDK sample. Your Xaml will look something like this:

    <UserControl.Resources> 
     
       <local:ThumbConverter x:Key="myThumbConverter" /> 
    
       <DataTemplate x:Key="ImageGalleryDataTemplate"> 
          <Border Background="#FF939598"> 
             <Image Source="{Binding Path=Thumbnail, Converter={StaticResource myThumbConverter}}" Height="130" Width="190" Stretch="UniformToFill"/> 
          </Border> 
       </DataTemplate> 
    </UserControl.Resources>
    
    <Grid Grid.Row="1"> 
       <GridView x:Name="PicturesGrid"
          ItemTemplate="{StaticResource ImageGalleryDataTemplate}" 
          CanReorderItems="True" 
          CanDragItems="True">       
          <GridView.ItemsPanel> 
             <ItemsPanelTemplate> 
                <WrapGrid MaximumRowsOrColumns="5" VerticalChildrenAlignment="Top" HorizontalChildrenAlignment="Center" /> 
             </ItemsPanelTemplate> 
          </GridView.ItemsPanel> 
       </GridView> 
    </Grid> 

    Does this help you accomplish your goals?

    Aaron



    Saturday, March 10, 2012 12:49 AM
  • Vinayak,

    So let's say you want to display images from a folder the user selected using a folder picker. This can be accomplished using the code in the StorageDataSource and GetVirtualizedFilesVector Sample, with a few changes. The following code allows the user to select a folder using the folder picker, then creates a file query. Then we create the data source that can be passed to a ListView or Gridview.

    var picker = new Windows.Storage.Pickers.FolderPicker();
    picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
    picker.FileTypeFilter.Add(".jpg");
    picker.FileTypeFilter.Add(".jpeg");
    picker.FileTypeFilter.Add(".png"); 
    
    var folder = await picker.PickSingleFolderAsync();
    
    var queryOptions = new Windows.Storage.Search.QueryOptions();
    queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
    queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;
    
    var fileQuery = folder.CreateFileQueryWithOptions(queryOptions);
    
    var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
        fileQuery,
        Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
        190,
        Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
        false
        );
    
    var dataSource = fif.GetVirtualizedFilesVector();
    PicturesGrid.ItemsSource = dataSource;

    There is more on file and folder pickers in the File and Folder Picker Sample.

    Does this help?

    Aaron

    Monday, March 12, 2012 5:09 PM

All replies

  • Vinayak,

    We have an SDK Sample that might help you out. Check out the StorageDataSource and GetVirtualizedFilesVector Sample.

    The code below, copied right out of the C# version of the above SDK Sample, shows how you can create a FolderQuery and then get a Virtualized Vector that you can plug right into your GridView's ItemsSource.

    var library = Windows.Storage.KnownFolders.PicturesLibrary; var queryOptions = new Windows.Storage.Search.QueryOptions(); queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep; queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable; var fileQuery = library.CreateFileQueryWithOptions(queryOptions); var fif = new Windows.Storage.BulkAccess.FileInformationFactory( fileQuery, Windows.Storage.FileProperties.ThumbnailMode.PicturesView, 190, Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale, false ); var dataSource = fif.GetVirtualizedFilesVector();

    PicturesGrid.ItemsSource= dataSource;

    To get the file thumbnails to show up in your app, you will have to create a DataTemplate that uses the ThumbnailConverter ValueConverter class also included in the SDK sample. Your Xaml will look something like this:

    <UserControl.Resources> 
     
       <local:ThumbConverter x:Key="myThumbConverter" /> 
    
       <DataTemplate x:Key="ImageGalleryDataTemplate"> 
          <Border Background="#FF939598"> 
             <Image Source="{Binding Path=Thumbnail, Converter={StaticResource myThumbConverter}}" Height="130" Width="190" Stretch="UniformToFill"/> 
          </Border> 
       </DataTemplate> 
    </UserControl.Resources>
    
    <Grid Grid.Row="1"> 
       <GridView x:Name="PicturesGrid"
          ItemTemplate="{StaticResource ImageGalleryDataTemplate}" 
          CanReorderItems="True" 
          CanDragItems="True">       
          <GridView.ItemsPanel> 
             <ItemsPanelTemplate> 
                <WrapGrid MaximumRowsOrColumns="5" VerticalChildrenAlignment="Top" HorizontalChildrenAlignment="Center" /> 
             </ItemsPanelTemplate> 
          </GridView.ItemsPanel> 
       </GridView> 
    </Grid> 

    Does this help you accomplish your goals?

    Aaron



    Saturday, March 10, 2012 12:49 AM
  • Hi Aaron,

    Thanks for your code..It worked.

    Can u eye on another problem pls...here it is..

    I am trying to get al the user picked folders in my app...The one like in sample in  previous ..But when I pick my folder and giving path something like this

    StorageFolder myFolder = await myBrowsedFolder.GetFolderAsyn(path)  

    but its throwing error as

    {"Value does not fall within the expected range."}

    Please help...

    Monday, March 12, 2012 8:17 AM
  • Vinayak,

    So let's say you want to display images from a folder the user selected using a folder picker. This can be accomplished using the code in the StorageDataSource and GetVirtualizedFilesVector Sample, with a few changes. The following code allows the user to select a folder using the folder picker, then creates a file query. Then we create the data source that can be passed to a ListView or Gridview.

    var picker = new Windows.Storage.Pickers.FolderPicker();
    picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
    picker.FileTypeFilter.Add(".jpg");
    picker.FileTypeFilter.Add(".jpeg");
    picker.FileTypeFilter.Add(".png"); 
    
    var folder = await picker.PickSingleFolderAsync();
    
    var queryOptions = new Windows.Storage.Search.QueryOptions();
    queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
    queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;
    
    var fileQuery = folder.CreateFileQueryWithOptions(queryOptions);
    
    var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
        fileQuery,
        Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
        190,
        Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
        false
        );
    
    var dataSource = fif.GetVirtualizedFilesVector();
    PicturesGrid.ItemsSource = dataSource;

    There is more on file and folder pickers in the File and Folder Picker Sample.

    Does this help?

    Aaron

    Monday, March 12, 2012 5:09 PM
  • Hi Aaron,

    Here, FileInformationFactory.GetVirtualizedItemsVector returns collection of FileInformation object, but how it can be converted into DataGroup and DataItems?, so that it can display similar to grid application's SampleDataGroup and SampleDataItem.

    Thanks


    CAT

    Tuesday, March 13, 2012 1:11 AM
  • How come GetVirtualizedFoldersVector, GetVirtualizedFilesVector returns same thing when I tried with my testing 2 folders with total of 30 images, it returns vector of 30 objects.


    CAT

    Tuesday, March 13, 2012 1:27 AM
  • Snekethan,

    Sorry you are having trouble. You should be able to create a data source of only folders by creating a Folder Query and then calling GetVirtualizedFoldersVector. See the code below:

    var library = Windows.Storage.KnownFolders.PicturesLibrary;
    var queryOptions = new Windows.Storage.Search.QueryOptions();
    queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
    queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;
    
    var folderQuery = library.CreateFolderQueryWithOptions(queryOptions);
    
    var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
        folderQuery,
        Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
        190,
        Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
        false
        );
    
    var dataSource = fif.GetVirtualizedFoldersVector(); 
    PicturesGrid.ItemsSource = dataSource;

    This code calls CreateFolderQueryWithOptions instead of the sister function for files.

    Hope this helps!

    Aaron

    Tuesday, March 13, 2012 3:55 PM
  • Snekethan,

    We don't give you this for free (we don't have a function that returns this as a nice data structure), but it is possible using nested groups.

    Ok, are you ready? This is a long one.

    First, you need to set up a data structure to contain your folders as groups. Here's mine:

    public class GroupedDataSource
    {
        public string Name { get; set; }
        public object VirtualizedVector { get; set; }
    }

    Then, in Xaml, set up your CVS and GridView for the Grouped Look.

    <UserControl.Resources>
        <local:ThumbConverter x:Key="myThumbConverter" />
    
        <CollectionViewSource x:Name="cvs"
                                IsSourceGrouped="True" 
                                ItemsPath="VirtualizedVector"/>
    
        <DataTemplate x:Key="ImageGalleryDataTemplate">
            <Border Background="#FF939598">
                <Image Source="{Binding Path=Thumbnail, Converter={StaticResource myThumbConverter}}" Height="130" Width="190" Stretch="UniformToFill"/>
            </Border>
        </DataTemplate>
    </UserControl.Resources>
    
    <Grid>
        <GridView x:Name="PicturesGrid" 
                  CanReorderItems="False" 
                  CanDragItems="False" 
                  SelectionMode="None" 
                  ItemsSource="{Binding Source={StaticResource cvs}}"  
                  ItemTemplate="{StaticResource ImageGalleryDataTemplate}" >
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
            <GridView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <Grid Margin="1,0,0,6">
                                <TextBlock
                                    AutomationProperties.Name="Group Title"
                                    Text="{Binding Name}"
                                    Style="{StaticResource PageHeaderTextStyle}"/>
                            </Grid>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </GridView.GroupStyle>
        </GridView>
    </Grid>

    The CVS will hold the Collection of Virtualized Vectors, and the GridView.ItemsSource is bound to the CVS. Finally, set up the Grouped Data Source.

    protected async void SetupGroupedDataSource()
    {
        var library = Windows.Storage.KnownFolders.PicturesLibrary;
        var queryOptions = new Windows.Storage.Search.QueryOptions();
        queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
        queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;
    
        var folderQuery = library.CreateFolderQueryWithOptions(queryOptions);
    
        var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
            folderQuery,
            Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
            190,
            Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
            false
            );
    
        var dataSource = await fif.GetFoldersAsync();
    
        ObservableCollection<GroupedDataSource> groups = new ObservableCollection<GroupedDataSource>();
        foreach (FolderInformation info in dataSource)
        {
            if (info != null)
            {
                var fileQuery = info.CreateFileQueryWithOptions(queryOptions);
    
                var fif2 = new Windows.Storage.BulkAccess.FileInformationFactory(
                    fileQuery,
                    Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
                    190,
                    Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
                    false
                    );
                groups.Add(new GroupedDataSource() { Name = info.Name, VirtualizedVector = fif2.GetVirtualizedFoldersVector() });
            }
        }
    
        cvs.Source = groups;
    }
     

    To set up my Groups, I ran a Folder Query for all my top-level folders in my Pictures Library, and I got a non-virtualized collection of these folders from GetFoldersAsync(). Then for each folder, I created a new File query and got the VirtualizedFilesVector. I create a new GroupedDataSource object for each folder and set the name and the VirtualizedVector. The CVS has been configured to look for this "VirtualizedVector" property, so the Folders and Files show up in the GridView!

    Hope this helps,

    Aaron

    Tuesday, March 13, 2012 4:30 PM
  • I got it, based on the query type (folder or file), virtualized vector returns collection of specific items, then, what is the rational for 3 APIs?


    CAT


    • Edited by Snekethan Wednesday, March 14, 2012 10:03 PM
    Tuesday, March 13, 2012 10:18 PM
  • Thank you, I did almost same thing, it works for few folders.

    But if you have large collection of folders, it does not provide fast-and-fluid experience. I'm still digging to find a better way for large collection of folders.


    CAT

    Wednesday, March 14, 2012 10:00 PM
  • Understood. This scenario is not currently officially supported.

    Please let me know what you end up with!

    Aaron

    Thursday, March 15, 2012 6:15 PM
  • When a folder's content is changed ( making copy of files in the folder), file query fires ContentsChanged event.

    How this change is notified to View?


    CAT

    Thursday, March 15, 2012 10:55 PM
  • With that Thumbnail class, does that let you specify thumbnails of any kind, such as a 680x1000 DVD-style cover or a 500x500 CD-style cover?  And if my image is half-size, like 340x500, would it stretch to fill or shrink to fill the named size?

    James

    Friday, March 16, 2012 4:18 PM
  • James,

    You can specify your preferences for the size of the thumbnail, and the API will use these preferences as a guide to return you the best match based on what thumbnail is available for the content. For instance, a video should return a frame extracted from the video, and music should return album art. The Image control used to display the thumbnail has a property called Stretch, which allows you to specify how to deal with size and aspect ration mismatching.

    You can find more information on options for getting thumbnails here and UX Guidelines here.

    Friday, March 16, 2012 6:53 PM
  • From my understanding, another approach is that using convertor returning collection of IGroupInfo ( Group Object) from VirtualizedVector on top level collection.

    This solution works great when virtualized vector items are available when GridView calls convertor to get the collection of IGrouopInfo during initial ItemSource data binding.  if MSFT allow us to make a request to get needed items from virtualized vector, which would work.  


    CAT

    Thursday, March 29, 2012 1:06 AM
  • Taking JS implementation and port it to C# may work.


    CAT

    Thursday, March 29, 2012 8:59 PM
  • MSFT's current listview implementation does not treat inner collection, bound by ItemsPath="VirtualizedVector", as virtualized vector, instead using as a regular collection which results in building all thumbnail images, so it could not handle large image sets.


    CAT


    • Edited by Snekethan Monday, April 09, 2012 6:48 PM
    Monday, April 09, 2012 5:31 PM
  • Hello Aaron,

    Is there a way to limit a number for VirtualizedVectors from fif2, or change the number of displayed items in VirtualizingStackPanel? I need to display just few preview images for each folder to improve app performance. Then once user selects a folder I can display all images from that folder. So far I was able to reduce the number of images by setting  NumberOfRowsOrColumns and changing Panel orientation. Is there a better way?

    Thanks.

    Wednesday, November 07, 2012 4:20 PM