Search code examples
c#listviewxamarinxamarin.formsdatatemplate

HeaderTemplate binding throws an exception in Xamarin forms


I have a xaml with a list view which looks like this

<?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:myControls="clr-namespace:MyControls;assembly=App.Visuals"
         x:Class="SearchResultPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <myControls:TravelCardItemTemplateSelector x:Key="TravelResultTemplate" />
            <myControls:TravelSearchHeaderTemplateSelector x:Key="HeaderTemplateSelector" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>        
            <ListView Grid.Row ="2" 
                      CachingStrategy="RecycleElement"
                      IsRefreshing="{Binding IsBusy}" 
                      IsPullToRefreshEnabled="true" 
                      RefreshCommand="{Binding RefreshCommand}"
                      ItemsSource="{Binding SearchResults}" 
                      Style="{DynamicResource ListStyle}"
                      HasUnevenRows="True" 
                      ItemTemplate="{StaticResource TravelResultTemplate}"
                      HeaderTemplate="{StaticResource HeaderTemplateSelector}"/>
    </ContentPage.Content>
</ContentPage>

The Template selector looks like this

public class TravelSearchHeaderTemplateSelector : DataTemplateSelector
{
    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        if (item== null)
        {
            return null;
        }

        var headerTempleTemplate= new DataTemplate(typeof(TransportSearchHeaderPanelCell));
        return headerTempleTemplate;
    }
}

And the xaml for the template is a view cell which looks like this

<?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="MyControls.TransportSearchHeaderPanelCell">
<ViewCell.View> <Grid ColumnSpacing="0" RowSpacing="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /><ColumnDefinition Width="*" /></Grid.ColumnDefinitions>
        <Button Text="Price" Grid.Column="0" />
        <Button Text="Departure" Grid.Column="1" BackgroundColor="Transparent"/>
        <Button Text="Fastest" Grid.Column="2" BackgroundColor="Transparent"/>
    </Grid>
</ViewCell.View>
</ViewCell>

On runtime, the application throws an exception

{System.InvalidOperationException: LoadTemplate should not be null
  at Xamarin.Forms.ElementTemplate.CreateContent () [0x00008] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\ElementTemplate.cs:74 
  at Xamarin.Forms.ListView.ValidateHeaderFooterTemplate (Xamarin.Forms.BindableObject bindable, System.Object value) [0x0000b] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\ListView.cs:587 
  at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty property, System.Object value, Xamarin.Forms.Internals.SetValueFlags attributes, Xamarin.Forms.BindableObject+SetValuePrivateFlags privateAttributes) [0x00071] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:359 
  at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value, System.Boolean fromStyle, System.Boolean checkAccess) [0x0005f] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:542 
  at Xamarin.Forms.BindableObject.SetValue (Xamarin.Forms.BindableProperty property, System.Object value) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\BindableObject.cs:83 
  at Xamarin.Forms.ListView.set_HeaderTemplate (Xamarin.Forms.DataTemplate value) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\ListView.cs:164 }

The binding should be simple enough so why would there be an exception.


Solution

  • Searching for the error message I came across this bug report, it seems a rather old bug already. Since you have verified that it does work from the code-behind, it seems the bug is still in there.

    The only way right now is to work around it from the code-behind and wait for them to fix it. Or, if you're brave enough; fix it yourself since Xamarin.Forms is open-source.