Home > Enterprise >  Display image in a ListView
Display image in a ListView

Time:11-21

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>
  • Related