Reputation: 117
I'm working on a UWP Desktop books application, and I can't display book cover images in a GridView. Questions:
Is GridView the best control for this or should I use a ListView?
Below are the XAML and Code Behind I'm using. If you can tell me what's wrong, I really appreciate it.
<GridView Name="gdvLibrary" Grid.Column="0" Grid.Row="2" Margin="10,0,20,3" Width="auto" Height="auto" HorizontalAlignment="Left" VerticalAlignment="Top" >
<GridView.ItemTemplate>
<DataTemplate x:Name="ImageTextDataTemplate" x:DataType="local:Book">
<StackPanel Height="280" Width="180" Margin="12" >
<Image Source="{x:Bind Cover.Source}" Height="180" Width="180" Stretch="UniformToFill"/>
<StackPanel Margin="0,12">
<TextBlock Text="{x:Bind Title}"/>
<TextBlock Text="{x:Bind Author}" Style="{ThemeResource CaptionTextBlockStyle}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="10" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
// Set the path to the app's books folder.
string path = @"D:\_BOOKS";
Image img = new Image();
// Get the folder object that corresponds to this absolute path in the file system.
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(path);
if (folder != null)
{
foreach (StorageFolder sf in await folder.GetFoldersAsync(Windows.Storage.Search.CommonFolderQuery.DefaultQuery))
{
img.Source = new BitmapImage(new Uri(sf.Path + @"\cover.jpg"));
string strAuthor = sf.DisplayName.Split(" - ")[0];
string strTitle = sf.DisplayName.Split(" - ")[1];
WCRVariables.Books.Add(new Book
{
Cover = img,
Title = strTitle,
Author = strAuthor,
Percentage = 0,
});
}
this.gdvLibrary.ItemsSource = WCRVariables.Books;
}
Upvotes: 0
Views: 385
Reputation: 2358
I suggest you use GridView control, because GridView works better for items that have images as their focal point. Besides, to bind the Image.Source property, you need to construct a BitmapImage instance like the following.
Xaml code:
<Image Source="{x:Bind Bitmap}" Height="180" Width="180" Stretch="UniformToFill"/>
Code behind:
public sealed partial class MainPage : Page
{
public ObservableCollection<Book> books { get; set; }
public MainPage()
{
this.InitializeComponent();
books = new ObservableCollection<Book>
{
new Book(){Title="English",Bitmap=new BitmapImage(new Uri("ms-appx:///Assets/1.JPG"))},
new Book(){Title="Math",Bitmap=new BitmapImage(new Uri("ms-appx:///Assets/2.JPG"))}
};
gdvLibrary.ItemsSource = books;
}
}
public class Book
{
public string Title { get; set; }
public BitmapImage Bitmap { get; set; }
}
Update:
If your image file is located in a user folder, you could use Storage Api to get the StorageFile object, then use StorageFile.OpenAsync method to get stream, finally set this stream as the source of Image. Please refer to the following code.
BitmapImage Bitmap= new BitmapImage();
var storageFile = await StorageFile.GetFileFromPathAsync(path);
using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read))
{
await Bitmap.SetSourceAsync(stream);
}
img.Source= Bitmap;
Note that you need to declare broadFileSystemAccess
capability in Package.appxmanifest like the following. Besides, you need to grant the permission in Settings app for this uwp app, access is configurable in Settings > Privacy > File system.
<Package
...
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
...
<Capabilities>
<rescap:Capability Name="broadFileSystemAccess" />
</Capabilities>
Upvotes: 1