locked
Databinding to a GridView (Windows 8 Store App - C++)

    Question

  • Hi everyone,

    We are developing a Windows Store App witch C++ and are experiencing the following issue:

    What we want is for a certain page to load all files in the "pictures library" ( in our case files ending with .ppan) and place them in a grid view. So far so good. But we also need to programmatically access some properties of these files. Preferably we want these files and their properties in some kind of Container such as a vector. And also we want to cast the item selected in the UI to one of our own datatypes/classes. The problem is we really have no idea how to go about this.

    Let's start off with the XAML code:

    In the page.resources we specify a data template for the GridView and declare the collectionViewSource and data converter:

    <Page.Resources>
            <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
            <x:String x:Key="AppName">Palette Move</x:String>
            
            <local:ThumbnailConverter x:Key="thumbnailConverter" />
    
            <!-- Collection of items displayed by this page -->
            <CollectionViewSource x:Name="itemsViewSource" />
    
            <DataTemplate x:Key="Custom190x130ItemTemplate" >
                <Grid Width="190" Height="170">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="130"/>
                        <RowDefinition Height="20" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="190" Height="130">
                        <!-- <Image Source="{Binding Path=Thumbnail, Converter={StaticResource thumbnailConverter}}" Stretch="None" Width="190" Height="130" /> -->
                        <Image x:Name="displayImage"  Source="{Binding Thumbnail, Converter={StaticResource thumbnailConverter}}"
                               Stretch="None" Width="190" Height="130" />
                    </Border>
                    <TextBlock Grid.Row="1" >
                        <Run Text="{Binding Name}" />
                    </TextBlock>
                </Grid>
            </DataTemplate>
         
        </Page.Resources>
     

    Next up is the code for the GridView:

    <!-- Horizontal scrolling grid used in most view states -->
            <GridView
                x:Name="itemGridView"
                AutomationProperties.AutomationId="ItemGridView"
                AutomationProperties.Name="Items"
                Grid.Row="1"
                Margin="0,-4,0,0"
                Padding="116,0,40,46"
                ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
                ItemTemplate="{StaticResource Custom190x130ItemTemplate}"
                BorderThickness="1"
                SelectionMode="Single"
                IsSwipeEnabled="True"
                IsItemClickEnabled="True"
                DoubleTapped="itemGridView_DoubleTapped"
                SelectionChanged="itemGridView_SelectionChanged"
                ItemClick="itemGridView_ItemClick"
                Tapped="itemGridView_Tapped"
                RightTapped="itemGridView_RightTapped"
                 />

    Here is code snippet of the private members in the header file behind the XAML code:

    // Stuff needed to Query the pictures library for panorama files when app is launched.
    		Windows::Storage::Search::QueryOptions^ m_FileQueryOptions;
    		Windows::Storage::Search::StorageFileQueryResult^ m_PanoramaFileQueryresult;
    		Windows::Storage::BulkAccess::FileInformationFactory^ m_PanoramaFileInformationFactory;


    Now for the .cpp file behind the XAML file. Here is the method OnNavigatedTo which reads the files:

    void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
    {
    	// NavigationHelper->OnNavigatedTo(e);
    	// Initialize file stuff to display panorama previews.
    	m_FileQueryOptions = ref new QueryOptions();
    	m_FileQueryOptions->FolderDepth = FolderDepth::Deep;
    	m_FileQueryOptions->IndexerOption = IndexerOption::UseIndexerWhenAvailable;
    	m_FileQueryOptions->SortOrder->Clear();
    	m_FileQueryOptions->FileTypeFilter->Append(".ppan");
    	SortEntry sortEntry;
    	sortEntry.PropertyName = "System.FileName";
    	sortEntry.AscendingOrder = true;
    	m_FileQueryOptions->SortOrder->Append(sortEntry);
    
    	m_PanoramaFileQueryresult = KnownFolders::PicturesLibrary->CreateFileQueryWithOptions(m_FileQueryOptions);
    	const UINT32 size = 190; // default size for PicturesView mode.
    	m_PanoramaFileInformationFactory = ref new FileInformationFactory(m_PanoramaFileQueryresult, ThumbnailMode::PicturesView, size, ThumbnailOptions::UseCurrentScale, true);
    //	itemsViewSource->Source = m_PanoramaFileInformationFactory->GetVirtualizedFilesVector();
    
    	itemsViewSource->Source = m_PanoramaFileInformationFactory->GetVirtualizedItemsVector();
    }

    And here is the code from the "convert" function in our converter:

    Object^ ThumbnailConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
    {
    	if (value != nullptr)
    	{
     		IRandomAccessStream^ thumbnailStream = dynamic_cast<IRandomAccessStream^>(value);
    		BitmapImage^ bitmapImage = ref new BitmapImage();
    		bitmapImage->SetSource(thumbnailStream);
    
    		return bitmapImage;
    	}
    	else
    	{
    		return DependencyProperty::UnsetValue;
    	}
    }

    And this is an example of the data structure we would like to use to store information on the files:

    This is just an example however and could be changed during later development:

    namespace AppBarControl
    {
    	[Windows::Foundation::Metadata::WebHostHidden]
    	//[Windows::UI::Xaml::Data::Bindable]
    	[Windows::UI::Xaml::Data::BindableAttribute]
    	public ref class PanoramaFile sealed
    	{
    	public:
    		PanoramaFile(Platform::String^ strName, Platform::SizeT nSize)
    		{
    			m_Name = strName;
    			m_Size = nSize;
    			m_Image = "Preview image unavailable";
    			m_Rank = 0;
    		}
    		property Platform::String^ Name
    		{
    			Platform::String^ get()
    			{
    				return m_Name;
    			}
    
    			void set(Platform::String^ strValue)
    			{
    				m_Name = strValue;
    			}
    		}
    
    		property Platform::String^ Image
    		{
    			Platform::String^ get()
    			{
    				return m_Image;
    			}
    
    			void set(Platform::String^ strValue)
    			{
    				m_Image = strValue;
    			}
    		}
    
    		property Platform::SizeT Size
    		{
    			Platform::SizeT get()
    			{
    				return m_Size;
    			}
    
    			void set(Platform::SizeT value)
    			{
    				m_Size = value;
    			}
    		}
    		property unsigned int Rank
    		{
    			unsigned int get()
    			{
    				return m_Rank;
    			}
    
    			void set(unsigned int value)
    			{
    				m_Rank = value;
    			}
    		}
    	private:
    		property Platform::String^ m_Name;
    		property Platform::String^ m_Image;
    		property Platform::SizeT m_Size;
    		property unsigned int m_Rank;
    	};
    }


    Now we want to access the currently selected item as an object of type PanoramaFile.

    void XAML_DirectXTest::MainPage::itemGridView_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
    {
            GridView^ gridView = safe_cast<GridView^>
    	Object^ pObject = gridView->SelectedItem;
    }

    Unfortunately, pObject is of type FileInformation and thus not castable to PanoramaFile. In most C# examples (found on the web) a simple cast to the custom DataTemplate type is sufficient. How can we achieve this in C++?

    Thank you in anticipation!

    Best regards,

    The Palette CAD Development Team


    Wednesday, March 19, 2014 4:57 PM

Answers

  • Hi,

    According to your code, you set the GridView itemsource to
    "m_PanoramaFileInformationFactory->GetVirtualizedItemsVector();", so you cannot get the type of girdview selectedItem to PanoramaFile class. The type of gridview class is FileInformation type. If you want to make the
    GridView Item type to PanoramaFile class, you should create  a collection which each item type is the PanoramaFile class and then set the collection to the Gridview itemSource. Please refer to the links below:
    http://msdn.microsoft.com/en-us/library/windows/apps/hh780650.aspx

    http://msdn.microsoft.com/en-us/library/windows/apps/hh758318.aspx


    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    Thursday, March 20, 2014 3:55 AM

All replies

  • Hi,

    According to your code, you set the GridView itemsource to
    "m_PanoramaFileInformationFactory->GetVirtualizedItemsVector();", so you cannot get the type of girdview selectedItem to PanoramaFile class. The type of gridview class is FileInformation type. If you want to make the
    GridView Item type to PanoramaFile class, you should create  a collection which each item type is the PanoramaFile class and then set the collection to the Gridview itemSource. Please refer to the links below:
    http://msdn.microsoft.com/en-us/library/windows/apps/hh780650.aspx

    http://msdn.microsoft.com/en-us/library/windows/apps/hh758318.aspx


    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    Thursday, March 20, 2014 3:55 AM
  • Thank you Anne Jing,

    That has definitely pointed us in the right direction. Your answer is much appreciated.

    Thursday, March 20, 2014 3:27 PM