Haybale100 Haybale100 - 1 month ago 9
C# Question

Linking two Lists of different types to a ListView

I am trying to make a

ListView
display both an Image and the name of the Image Selected. So far I have successfully bound a
List<BitmapImage>
to the ListView.ItemsSource that displays both the
Image
element along with a
Textblock
element inside a
ItemTemplate
, I have also successfully added the name of each
Image
to a separate
List<string>
. Now this is where I am stuck, How can I bind both the
List<BitmapImage>
and
List<string>
to the single ListView and therefore each List Item's respected field.

Code snippets are given below:

XAML ListView:

<ListView x:Name="listView_ViewPhotos" Visibility="Collapsed">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="0,5,0,5">
<Grid.ColumnDefinitions>
<!--Image Column-->
<ColumnDefinition Width="150"/>
<!--Name Column-->
<ColumnDefinition MinWidth="{Binding ActualWidth, ElementName=pageRoot, Mode=OneWay}"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageList}" Height="100" Width="150" Stretch="UniformToFill" Grid.Column="0"/>
<TextBlock x:Name="txt_Listimg_Caption" Foreground="{ThemeResource ButtonForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="WrapWholeWords" Height="40" Margin="15,0,15,0" FontSize="25" Text="{Binding ImageName}" Grid.Column="1" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>


C#

public List<string> ImageName = new List<string>();
private async void appBar_GetFiles_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.ViewMode = PickerViewMode.List;
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".gif");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.FileTypeFilter.Add(".jpeg");

IReadOnlyList<StorageFile> filelist = await filePicker.PickMultipleFilesAsync();
foreach (var file in filelist)
{
if (file != null)
{
string FileName = file.Name;
//var imageData = await activeFolder.GetFileAsync(FileName);
//var imageData = await KnownFolders.PicturesLibrary.GetFileAsync(FileName);
BitmapImage bitmapImage;
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
}
ImageName.Add(FileName);
ImageList.Add(bitmapImage);
}
else break;
}
listView_ViewPhotos.ItemsSource = null;
listView_ViewPhotos.ItemsSource = ???;

gridView_ViewPhotos.ItemsSource = null;
gridView_ViewPhotos.ItemsSource = ???;

Answer

Instead of 2 lists, just use 1:

1st, Create a new class, let's call it ImageDetails. This class contains 2 properties, 1 is the image itself, 1 is the Image's name

public class ImageDetails
{
    public BitmapImage Image{get;set:}
    public string ImageName{get;set;}
}

So now, you instead of loading 2 lists, just call List<ImageDetails>

Example for Add:

List<ImageDetails> list = new List<ImageDetails>();
ImageDetails _imgDetails = new ImageDetails();
_imgDetails.Image = bitmapImage;
_imgDetails.ImageName = FileName;
list.Add(_imgDetails);

Example for GetAll:

foreach(var img in list)
{
    var image = img.Image; //this is your BitmapImage
    var name = img.ImageName; //this is your image Name
    //other work
}