'Xamarin Forms ListViewCell not updating Image

I am trying to get an image to show in my custom ViewCell, however, setting it manually doesn't work.

I am first creating a list of my custom view cells and setting the image through there. After I have all the view cells I need, I add them to a list and set that list to be the ItemSource for the listview. However; the image doesn't display even though it should through some very simplistic code. Am I missing something?

The following is the ContentPage that I am loading the view cells in.

public partial class InAppStorePage : ContentPage
{

    private List<ViewCell> cells;
    private Store inAppStore;

    public InAppStorePage()
    {
        InitializeComponent();
        InitializeObjects();
    }

    private void InitializeObjects()
    {
        cells = new List<ViewCell>();
        inAppStore = AppStore.CurrentStore;
    }

    protected override void OnAppearing()
    {
        SetListViewTemplate();
        LoadProductsIntoListView();
        SetListViewItemSource();
    }

    private void LoadProductsIntoListView()
    {
        LoadPurchasedProductsIntoListView();
        LoadPendingProductsIntoListView();
        LoadNonPurchasedProductsIntoListView();
    }

    private void SetListViewTemplate()
    {
        InAppProductsListView.ItemTemplate = new DataTemplate(typeof(InAppStoreViewCell));
    }

    private void LoadPurchasedProductsIntoListView()
    {
        List<ViewCell> purchasedProductCells = new List<ViewCell>();
        foreach (InAppProduct purchasedProduct in inAppStore.GetListOfPurchasedProducts())
        {
            InAppStoreViewCell purchasedProductViewCell = new InAppStoreViewCell();

            //The Line in Question
            purchasedProductViewCell.ProductImage.Source = purchasedProduct.GetIcon().Source;

            purchasedProductCells.Add(purchasedProductViewCell);
        }
        cells.AddRange(purchasedProductCells);
    }

    private void LoadPendingProductsIntoListView()
    {
        List<ViewCell> pendingPurchasedProductCells = new List<ViewCell>();
        foreach (InAppProduct pendingPurchaseProduct in inAppStore.GetListOfPendingPurchaseProducts())
        {
            InAppStoreViewCell pendingPurchaseProductCell = new InAppStoreViewCell();

            //The Line in Question
            pendingPurchaseProductCell.ProductImage.Source = pendingPurchaseProduct.GetIcon().Source;

            pendingPurchasedProductCells.Add(pendingPurchaseProductCell);
        }
        cells.AddRange(pendingPurchasedProductCells);
    }

    private void LoadNonPurchasedProductsIntoListView()
    {
        List<ViewCell> nonPurchasedProductCells = new List<ViewCell>();
        foreach (InAppProduct nonPurchasedProduct in inAppStore.GetListOfProductsThatHaventBeenPurchased())
        {
            InAppStoreViewCell nonPurchasedProductCell = new InAppStoreViewCell();

            //The Line in Question
            nonPurchasedProductCell.ProductImage.Source = nonPurchasedProduct.GetIcon().Source;

            nonPurchasedProductCells.Add(nonPurchasedProductCell);
        }
        cells.AddRange(nonPurchasedProductCells);
    }

    private void SetListViewItemSource()
    {
        InAppProductsListView.ItemsSource = null;
        InAppProductsListView.ItemsSource = cells;
    }

}

And the following is the C# file of the custom viewcell and its accompanying xaml file

    [XamlCompilation(XamlCompilationOptions.Compile)]
public partial class InAppStoreViewCell : ViewCell
{
    public InAppStoreViewCell()
    {
        InitializeComponent();
    }

    public Image ProductImage
    {
        get
        {
            return CellProductIcon;
        } 

        set
        {
            CellProductIcon = value;
        }
    }

    public void SetColor(Color color)
    {
        ProductImage.BackgroundColor = color;
    }

    public Label ProductNameLabel
    {
        get
        {
            return CellProductNameLabel;
        }

        set
        {
            CellProductNameLabel = value;
        }
    }

    public Label ProductStatusLabel
    {
        get
        {
            return CellProductStatus;
        }

        set
        {
            CellProductStatus = value;
        }
    }

    public Label ProductPriceLabel
    {
        get
        {
            return CellProductPriceLabel;
        }

        set
        {
            CellProductPriceLabel = value;
        }
    }

}

The Xaml file

<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Alan.Views.UIElements.InAppStoreViewCells.InAppStoreViewCell">
  <ViewCell.View>
      <RelativeLayout>
            <RelativeLayout x:Name="TopContainer"
                            BackgroundColor="CornflowerBlue"
                            RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
                            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.75}">
                <Image x:Name="CellProductIcon"
                       BackgroundColor="Indigo"
                       Aspect="Fill"
                       RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1.0}"
                       RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1.0}"/>
            </RelativeLayout>
            <RelativeLayout x:Name="BottomContainer"
                            BackgroundColor="Orange"
                            RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
                            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.25}"
                            RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.75}">
                <Label x:Name="CellProductNameLabel"/>
                <Label x:Name="CellProductStatus"/>
                <Label x:Name="CellProductPriceLabel"/>
            </RelativeLayout>
        </RelativeLayout>
  </ViewCell.View>
</ViewCell>

Any help would be seriously appreciated because this super simplistic thing is driving me crazy :/



Solution 1:[1]

I think there's something wrong with the way you use it.

For example:

1.You didn't set the BindableProperty for your ViewCell.

2.Why do you assign cells to InAppProductsListView.ItemsSource while the type of its child element is ViewCell?

 private List<ViewCell> cells;
 cells = new List<ViewCell>();

InAppProductsListView.ItemsSource = cells;

We should assign our special data list to the ItemsSource of listView.

You can refer to the following sample code:

      public ListPageCS()
    {
        Title = "BindingContextChanged Code Demo";
        Padding = 10;

        var customCell = new DataTemplate(typeof(CustomCell));
        customCell.SetBinding(CustomCell.NameProperty, "Name");
        customCell.SetBinding(CustomCell.AgeProperty, "Age");
        customCell.SetBinding(CustomCell.LocationProperty, "Location");

        var listView = new ListView
        {
            ItemTemplate = customCell
        };

        var button = new Button { Text = "Change Binding Context" };
        button.Clicked += (sender, e) =>
        {
            listView.ItemsSource = Constants.People;
        };

        Content = new StackLayout
        {
            Children = {
                listView,
                button
            }
        };
    }

For how to use custom ViewCell , you can check document Customizing ListView Cell Appearance.

And you can check up the sample included above link.

The sample is here: https://github.com/xamarin/xamarin-forms-samples/tree/main/UserInterface/ListView/BindingContextChanged .

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jessie Zhang -MSFT