Search code examples
c#xamarin.formsviewmodeldatatemplateitemtemplate

Set up DataTemplate for CarouselView


Hi I am trying to set up a CarouselView in my ViewModel. Here I Have a problem with the setting of the ItemTemplate.

Setup

For your reference I try to define the CarouselView carouselView:

CarouselView carouselView = new CarouselView()
    {
               
        ItemsSource = items,
        IndicatorView = indicatorView,
        ItemTemplate = viewDataTemplate
    };

The IndicatorView is working:

private IndicatorView indicatorView = new IndicatorView()
    {
        IndicatorColor = Color.LightGray,
        IndicatorSize = 10,
        SelectedIndicatorColor = Color.DarkGray,
        IndicatorsShape = IndicatorShape.Circle,
        VerticalOptions = LayoutOptions.End,
        HorizontalOptions = LayoutOptions.Center,
        Margin = new Thickness(0, 0, 0, 20)
    };

And the items are set as the following ones:

private ContentView[] CarouselItems()
        {
            ContentView[] items = new ContentView[5] {
                MapView(), SpeedView(), PaceView(), HeightView(), StepLengthView() };


            return items;

        }

        private ContentView StepLengthView()
        {
            ContentView view = new ContentView()
            {
                Content = new Label()
                {
                    Text = "Schrittlängenverlauf"
                }
            };

            return view;
        }

        private ContentView HeightView()
        {
            ContentView view = new ContentView()
            {
                Content = new Label()
                {
                    Text = "Höhenverlauf"
                }
            };

            return view;
        }

        private ContentView PaceView()
        {
            ContentView view = new ContentView()
            {
                Content = new Label()
                {
                    Text = "Balkendiagram: Pace"
                }
            };

            return view;
        }

        private ContentView SpeedView()
        {

            ContentView view = new ContentView()
            {
                Content = new Label()
                {
                    Text = "Geschwindigkeitsdiagram"
                }
            };

            return view;
        }

        private ContentView MapView()
        {
            Polygon route = new Polygon
            {
                StrokeWidth = 8,
                StrokeColor = Color.FromHex("#1BA1E2"),
                Geopath =
                {
                    new Position(47.6368678, -122.137305),
                    new Position(47.6368894, -122.134655),
                    new Position(47.6359424, -122.134655),
                    new Position(47.6359496, -122.1325521),
                    new Position(47.6424124, -122.1325199),
                    new Position(47.642463,  -122.1338932),
                    new Position(47.6406414, -122.1344833),
                    new Position(47.6384943, -122.1361248),
                    new Position(47.6372943, -122.1376912)
                }
            };

            Map map = new Map()
            {
                HasScrollEnabled = false,
                HasZoomEnabled = false,
            };

            map.MapElements.Add(route);

            ContentView view = new ContentView()
            {
                Content = map
            };

            return view;
        }

The reason why I want my ItemSources to be ContentViews is because I want to show different thinks in the CarouselView (Map, Image, Chart,...).

The part with the bug (Edit):

var viewDataTemplate = new DataTemplate(() =>
            {
                var grid = new Grid();

                var view = new ContentView();

                view.SetBinding(ContentView.ContentProperty, "Content");

                grid.Children.Add(view);

                return new ViewCell { View = grid };
            });

Problem

If I try to run the code I get

System.InvalidCastException: 'Specified cast is not valid.'

I think it is a problem with the definition of the DataTemplate: If I comment out the the corresponding line like this:

CarouselView carouselView = new CarouselView()
    {
               
        ItemsSource = items,
        IndicatorView = indicatorView,
        //ItemTemplate = viewDataTemplate
    };

I do not get an error, but of course the CarouselView does not displays the Views correct ( as you can see here: image).

Does anyone sees my mistake and can help me.


Solution

  • From CarouselView Microsoft docs

    When using CarouselView, never set the root element of your DataTemplate objects to a ViewCell. This will result in an exception being thrown because CarouselView has no concept of cells.

    Your viewDataTemplate should not return a ViewCell:

    var viewDataTemplate = new DataTemplate(() =>
    {
        var grid = new Grid();
        var view = new ContentView();
        view.SetBinding(ContentView.ContentProperty, "Content");
        grid.Children.Add(view);
        return grid;
    });