I am trying to populate my gridview with Photos from the Pictures library using data virtualization and compiled binding.
I've taken the Microsoft UWP (Data Virtualization Sample) and using its FileSource as my base, I modified it to use my own Picture object and tried to apply it to my UWP app. All I am getting is a blank page, and the designer is throwing an exception.
I want to use x:Bind to bind to my data source object in my model as I am using MVVM and don't want code-behind.
I couldn't get this to work in my app so I wrote a small test app that isn't even MVVM and tried to use x:Bind with my data source as an object in the code behind and it fails as to bind to the collection as well.
I can get this work with my Picture object if I set the gridview's source directly in my code-behind (which is what the sample is doing).
async void initdata()
{
StorageLibrary pictures = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
string path = pictures.SaveFolder.Path;
FileDataSource ds = await FileDataSource.GetDataSoure(path);
if (ds.Count > 0)
{
PicturesGrid.ItemsSource = ds;
}
else
{
MainPage.Current.NotifyUser("Error: The pictures folder doesn't contain any files", NotifyType.ErrorMessage);
}
}
The FileDataSource is defined as follows:
/// <summary>
/// A custom datasource over the file system that supports data virtualization
/// </summary>
public class FileDataSource : INotifyCollectionChanged, System.Collections.IList, IItemsRangeInfo
{
...
}
In my code, I have created the PicturesCollection as a property:
public sealed partial class MainPage : Page
{
public FileDataSource _PicturesCollection;
public FileDataSource PicturesCollection { get; private set; }
public MainPage()
{
this.InitializeComponent();
PicturesGrid.ContainerContentChanging += PicturesGrid_ContainerContentChanging;
PicturesCollection = null;
initdata();
}
private void PicturesGrid_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (!args.InRecycleQueue)
{
// Sets a textblock in each item indicating its index
//FrameworkElement ctr = (FrameworkElement)args.ItemContainer.ContentTemplateRoot;
//if (ctr != null)
//{
// TextBlock t = (TextBlock)ctr.FindName("idx");
// t.Text = args.ItemIndex.ToString();
//}
}
}
async void initdata()
{
StorageLibrary pictures = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
string path = pictures.SaveFolder.Path;
_PicturesCollection = await FileDataSource.GetDataSoure(path);
if (_PicturesCollection.Count > 0)
{
PicturesCollection = _PicturesCollection;
//PicturesGrid.ItemsSource = ds;
}
}
}
and bound it to my GridView:
<Grid Grid.Row="1">
<GridView x:Name="PicturesGrid"
SelectionMode="Single"
ShowsScrollingPlaceholders="False"
ItemsSource="{x:Bind PicturesCollection}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:Picture" >
<Grid Width="200" Height="80">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.RowSpan="2" Background="DimGray" Opacity="0.8" />
<Image Width ="130"
HorizontalAlignment="Center"
Stretch="Uniform"
Source="{x:Bind ImageThumbNail, Converter ={StaticResource StorageItemThumbnailoImageSourceConverter}, Mode=OneWay}" />
<TextBlock Grid.Row="1"
MaxHeight="30"
Text="{x:Bind Name}"
Foreground="White"
HorizontalAlignment="Center"
TextTrimming="CharacterEllipsis"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
This gives me a blank page, but if I set it in code-behind, it works. Can anyone tell me why this is so? What am I missing?