I'm desperately trying to populate my ListView with downloaded Graphics at runtime. So far I've tried several approaches but i couldn't get it to work properly.
The Download and display for itself (i tested in a canvas called pic, so there's still fragments in the code) works fine, but the ListView won't display the damn image.
C# code:
private async void LoadFlags(RootAutomarken automarken)
{
Image flag = new Image();
var client = new HttpClient();
foreach (var item in automarken.Automarken)
{
flag = await LoadFlag(item.Land, client);
mainList.Items.Add(new CarListItem { Logo = flag, Name = item.Name, Land = item.Land, Region = item.Region});
}
}
private async Task<Image> LoadFlag(string countrycode, HttpClient client)
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://www.countryflagsapi.com/png/" countrycode),
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
Stream imageStreamSource = await response.Content.ReadAsStreamAsync();
PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
// Draw the Image
Image myImage = new Image();
myImage.Source = bitmapSource;
myImage.Stretch = Stretch.Uniform;
myImage.Height = 15;
myImage.Width = 15;
myImage.Margin = new Thickness(20);
pic.Children.Add(myImage);
return myImage;
}
XAML:
<Window.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Background" Value="#505050" />
<Setter Property="Foreground" Value="#FFDADADA" />
<Setter Property="BorderBrush" Value="#606060" />
</Style>
</Window.Resources>
<Grid>
<ListView x:Name="mainList" Background="#202020" Margin="20,100,20,10" BorderBrush="#505050" Foreground="#FFDADADA">
<ListView.View>
<GridView>
<GridViewColumn Header="Logo" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Logo}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="565"/>
<GridViewColumn Header="Land" DisplayMemberBinding="{Binding Land}" Width="50"/>
<GridViewColumn Header="Region" DisplayMemberBinding="{Binding Region}" Width="50"/>
</GridView>
</ListView.View>
</ListView>
<Canvas x:Name="pic"></Canvas>
</Grid>
CodePudding user response:
You are trying to bind the Source
property of an Image
element (in XAML) to another Image
element (created in code). That won't work.
Do not use the Image
type in view model code. Image
is a view element.
Change the type of the Logo
property and the return type of the to LoadFlag
method to ImageSource
.
private static async Task<ImageSource> LoadFlag(
string countrycode, HttpClient client)
{
using var response = await client.GetAsync(
$"https://www.countryflagsapi.com/png/{countrycode}");
response.EnsureSuccessStatusCode();
using var stream = await response.Content.ReadAsStreamAsync();
return BitmapFrame.Create(stream,
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
}
...
ImageSource flag = await LoadFlag(item.Land, client);
mainList.Items.Add(new CarListItem { Logo = flag, ... });
and bind it like this:
<Image Width="15" Height="15" Margin="20" Source="{Binding Logo}"/>
CodePudding user response:
You can't bind the Source
property of an Image
element to another Image
element.
Try this:
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Logo}" />
</DataTemplate>
</GridViewColumn.CellTemplate>