简体   繁体   中英

Unable to display DataTemplate from DataTemplateSelector in CarouselView in Xamarin Forms

I have a carouselview in my Xam.Forms project. I have also created 3 ContentViews (one for each DataTemplate). My template selector class looks like this

public class DashboardTemplateSelector : DataTemplateSelector
{
    public DataTemplate QuickMessageTemplate { get; set; }
    public DataTemplate DataViewTemplate { get; set; }
    public DataTemplate LastUsedTemplate { get; set; }

    public DashboardTemplateSelector()
    {
        QuickMessageTemplate = new DataTemplate(typeof(QuickMessage));
        DataViewTemplate = new DataTemplate(typeof(DataView));
        LastUsedTemplate = new DataTemplate(typeof(LastusedView));
    }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        var cv = (Frame)item;
        DataTemplate rv = null;

        switch(cv.ClassId)
        {
            case "data":
                rv = DataViewTemplate;
                break;
            case "quick":
                rv= QuickMessageTemplate;
                break;
            case "last":
                rv = LastUsedTemplate;
                break;
        }
        return rv;
    }

Nothing out of the ordinary and I have the ClassId on each frame within the ContentView set to match the name in the switch.

When I build the app and run it, it looks fine but there is nothing in the CarouselView and a break point set in the OnSelectTemplate method (the first line) is never hit.

My XAML for the carouselview is this

<ContentPage.Resources>
    <ResourceDictionary>
        <local:DashboardTemplateSelector x:Key="templateSelector" />
    </ResourceDictionary>
</ContentPage.Resources>

<CarouselView Grid.Row="2" PeekAreaInsets="12" Margin="8" ItemTemplate="{StaticResource templateSelector}" HeightRequest="200" BackgroundColor="BlueViolet" />

The view shows (can see the background colour) but nothing in the view itself.

I've only checked this on a physical android device and not on iOS, but I'm guessing the same retult. My guess is that I can't cast to a Frame for the object, but I'm not sure.

To populate data, you have to set an ItemsSource via DataBinding or Code-Behind. Then your DataTemplateSelector will be hit with each item of the ItemsSource as object item. Please see the documentation here: https://docs.microsoft.com/fr-fr/xamarin/xamarin-forms/user-interface/carouselview/layout

<CarouselView Grid.Row="2" PeekAreaInsets="12" Margin="8" ItemsSource="{Binding ViewsViewModels} ItemTemplate="{StaticResource templateSelector}" HeightRequest="200" BackgroundColor="BlueViolet" />

The item in OnSelectTemplate is itemsource data. Change the item to container and use CarouselView instead of Frame . Do not forget to set the ClassId of your CarouselView .

The whold project for your reference.

Xaml:

 <ContentPage.Resources>
    <ResourceDictionary>
        <local:DashboardTemplateSelector x:Key="templateSelector" />
    </ResourceDictionary>
</ContentPage.Resources>


<CarouselView
    Grid.Row="2"
    Margin="8"
    ClassId="data"
    HeightRequest="200"
    ItemTemplate="{StaticResource templateSelector}"
    ItemsSource="{Binding infos}"
    PeekAreaInsets="12" />

Code behind:

public partial class MainPage : ContentPage
{
    public ObservableCollection<Info> infos { get; set; }
    public MainPage()
    {
        InitializeComponent();
        infos = new ObservableCollection<Info>()
        {
            new Info{ DataViewText="DataViewText1", LastusedViewText="LastusedViewText1", QuickMessageText="QuickMessageText1"},
            new Info{ DataViewText="DataViewText2", LastusedViewText="LastusedViewText2", QuickMessageText="QuickMessageText2"},
            new Info{ DataViewText="DataViewText3", LastusedViewText="LastusedViewText3", QuickMessageText="QuickMessageText3"},
            new Info{ DataViewText="DataViewText4", LastusedViewText="LastusedViewText4", QuickMessageText="QuickMessageText4"},
        };
        this.BindingContext = this;

    }
}
public class Info
{
    public string QuickMessageText { get; set; }
    public string DataViewText { get; set; }
    public string LastusedViewText { get; set; }
}

QuickMessage, DataView and LastusedView is a contentview with label which binding a text.

QuickMessage:

<Label Text="{Binding QuickMessageText}" />

DataView:

 <Label Text="{Binding DataViewText}" />

LastusedView:

  <Label Text="{Binding LastusedViewText}" />

DashboardTemplateSelector:

public class DashboardTemplateSelector : DataTemplateSelector
{
    public DataTemplate QuickMessageTemplate { get; set; }
    public DataTemplate DataViewTemplate { get; set; }
    public DataTemplate LastUsedTemplate { get; set; }

    public DashboardTemplateSelector()
    {
        QuickMessageTemplate = new DataTemplate(typeof(QuickMessage));
        DataViewTemplate = new DataTemplate(typeof(DataView));
        LastUsedTemplate = new DataTemplate(typeof(LastusedView));
    }

   
    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        var cv = (CarouselView)container;
        DataTemplate rv = null;

        switch (cv.ClassId)
        {
            case "data":
                rv = DataViewTemplate;
                break;
            case "quick":
                rv = QuickMessageTemplate;
                break;
            case "last":
                rv = LastUsedTemplate;
                break;
        }
        return rv;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM