Search code examples
xamarin.formsdata-bindingitemssource

Xamarin Forms CarouselView.ItemsSource not working with Bindings


In a simple example using Xamarin Forms CarouselView, I attempt to set the ItemsSource using Binding to a public object (get property), but it doesn't work. The CarouselView shows up but doesn't have any data to view. Below is my Xaml and code-behind:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="CVApp.OtherPage">
    <ContentPage.Content>
        <StackLayout>
            <CarouselView x:Name="_carouselView" ItemsSource="{Binding Stuffs}">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <Frame
                               BorderColor="DarkGray"
                               CornerRadius="5"
                               Margin="20"
                               HeightRequest="50"
                               HorizontalOptions="Center"
                               VerticalOptions="CenterAndExpand">
                                <StackLayout>
                                    <Label Text="{Binding Text}" />
                                </StackLayout>
                            </Frame>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace CVApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class OtherPage : ContentPage
    {
        private List<Stuff> _stuffs;

        public List<Stuff> Stuffs
        {
            get
            {
                return this._stuffs;
            }
        }

        public OtherPage()
        {
            InitializeComponent();

            _stuffs = new List<Stuff>();

            for (int i = 0; i < 10; i++)
            {
                _stuffs.Add(new Stuff(i));
            }
        }
    }

    public class Stuff
    {
        public string Text { get; set; }

        public Stuff(int i)
        {
            this.Text = i.ToString();
        }
    }
}

However, if I just remove the ItemsSource="{Binding Stuffs}" from the Xaml code and instead set the ItemsSource directly in the code-behind, it works fine (see code below). Can anyone advise me on what is wrong with my Bindings code?

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="CVApp.OtherPage">
    <ContentPage.Content>
        <StackLayout>
            <CarouselView x:Name="_carouselView" ItemsSource="{Binding Stuffs}">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <Frame
                               BorderColor="DarkGray"
                               CornerRadius="5"
                               Margin="20"
                               HeightRequest="50"
                               HorizontalOptions="Center"
                               VerticalOptions="CenterAndExpand">
                                <StackLayout>
                                    <Label Text="{Binding Text}" />
                                </StackLayout>
                            </Frame>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace CVApp
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class OtherPage : ContentPage
    {
        private List<Stuff> _stuffs;

        public List<Stuff> Stuffs
        {
            get
            {
                return this._stuffs;
            }
        }

        public OtherPage()
        {
            InitializeComponent();

            _stuffs = new List<Stuff>();

            for (int i = 0; i < 10; i++)
            {
                _stuffs.Add(new Stuff(i));
            }

            this._carouselView.ItemsSource = this._stuffs;
        }
    }

    public class Stuff
    {
        public string Text { get; set; }

        public Stuff(int i)
        {
            this.Text = i.ToString();
        }
    }
}

Solution

  • You should add BindingContext = this; in your Page's constructor.

    Here is code.

        public partial class MainPage : ContentPage
    {
        private List<Stuff> _stuffs;
        public List<Stuff> Stuffs
        {
            get
            {
                return _stuffs;
            }
        }
    
    
    
    
        public MainPage()
        {
            InitializeComponent();
    
            _stuffs = new List<Stuff>();
    
            for (int i = 0; i < 10; i++)
            {
                _stuffs.Add(new Stuff(i));
            }
            BindingContext = this;
    
        }
    
        public class Stuff
        {
            public string Text { get; set; }
    
            public Stuff(int i)
            {
                this.Text = i.ToString();
            }
        }
    }
    

    Here is running GIF.

    enter image description here