Search code examples
c#.netxamlmaui

CollectionView not displaying content in .net MAUI


<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MonkeyFinder.TopicsPage"
             xmlns:model="clr-namespace:MonkeyFinder.Model"
             xmlns:viewmodel="clr-namespace:MonkeyFinder.ViewModel"
             xmlns:control="clr-     namespace:Syncfusion.Maui.ProgressBar;assembly=Syncfusion.Maui.ProgressBar">

<CollectionView BackgroundColor="Transparent">

    <CollectionView.ItemTemplate>

        <DataTemplate>

            <Image Source="traffic_light.png"/>

        </DataTemplate>

    </CollectionView.ItemTemplate>
    
</CollectionView>

Hi .net MAUI beginner here, was trying to create a collectionview with data binding within a tabbed page but couldn't get the content to appear. Simplified the CollectionView but still couldn't get any content within the collectionview to show. I know the collectionview is visible because when i change the backgroundcolour of the collectionview the colour of the page changes. I can also see content within the contentpage if it is outside the collectionview. No idea what i'm doing wrong :/


Solution

  • CollectionView is not a layout. It is a container for collections of data, hence the name.

    If you want to display an image like in the code in your question, just use a Grid or a VerticalStackLayout:

    <Grid>
        <Image Source="traffic_light.png"/>
    </Grid>
    

    If you want to use data binding, you need a binding source, e.g. an ObservableCollection<T> where T is the data type of the elements of the collection.

    Let's assume you have a ViewModel, you can create such a collection, let's call it Items:

    public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<string> items;
        public ObservableCollection<string> Items
        {
            get => items;
            set
            {
                if(items == value) return;
                items = value;
                OnPropertyChanged();
            }
        }
    
        public MyViewModel()
        {
            // populate Items
            Items = new ObservableCollection<string>()
            {
                "hello", "bye", "ciao"
            };
        }
    
        // skipping INotifyPropertyChanged implementation for brevity
    }
    

    In your XAML, you then need to set the Items as the ItemsSource of the CollectionView via a Binding expression:

    <CollectionView
      ItemsSource="{Binding Items}"
      BackgroundColor="Transparent">
    
        <CollectionView.ItemTemplate>
    
            <DataTemplate>
    
                <Image Source="traffic_light.png"/>
    
            </DataTemplate>
    
        </CollectionView.ItemTemplate>
        
    </CollectionView>
    

    This also requires that you set the BindingContext of the page in the code-behind:

    public partial class TopicsPage : ContentPage
    {
        public TopicsPage()
        {
            InitializeComponent();
            BindingContext = new MyViewModel();
        }
    }