FreakyAli
FreakyAli

Reputation: 16409

Binding not working when we use ListView with DataTemplate through Resources.(MVVM)

I have a ListView which gets its ItemTemplate from a Resource file.

I have a Resource dictionary as below!

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
         xmlns:common="clr-namespace:xx.Common;assembly=xx"
         x:Class="xx.ResourceDictionaries.BaseHomeStyles"> 

 <DataTemplate x:Key="ListItemTemplate">
    <ViewCell>
        <Grid Padding="{StaticResource ListPadding}">
            <Grid.RowDefinitions>
                <RowDefinition Height="1.5*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <ffimageloading:CachedImage Grid.Row="0" Aspect="Fill" DownsampleToViewSize="True" BitmapOptimizations="True"
                                            ErrorPlaceholder = "nopreviewlandscape" LoadingPlaceholder = "loadingicon" Source="{Binding TripImage}" />
            <StackLayout Grid.Row="1">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="4*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Text="{Binding TripName}" FontAttributes="Bold" TextColor="{StaticResource PrimaryColor}" />
                    <Image Grid.Column="1" Source="downarrow" Rotation="-90" BackgroundColor="{Binding PrimaryColor}"/>
                </Grid>
                <Label Text="{Binding ReferenceNumber}" FontAttributes="Bold"/>
                <Label Text="{Binding TripUIStartDate}" />
                <Label Text="{Binding DaysDetails}" TextColor="{StaticResource AppQuaternaryBackground}" />
            </StackLayout>
            <!--<Grid.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding Path=BindingContext.ToItineraryCommand, Source={x:Reference HomeList}}" CommandParameter="{Binding .}"/>
                </Grid.GestureRecognizers>-->
        </Grid>
    </ViewCell>
</DataTemplate>
</ResourceDictionary>

Then I use this DataTemplate as the ItemTemplate something like this:

<ListView HasUnevenRows = "true" ItemsSource="{Binding CurrentTripInfo}" BackgroundColor="Transparent"
       CachingStrategy="RecycleElement" x:Name="HomeList" SeparatorVisibility ="Default" Grid.Row="1" ItemTemplate="{StaticResource ListItemTemplate}" />

I am adding this ResourceDictionary something like this :

 <ContentPage.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <resources:BaseHomeStyles/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</ContentPage.Resources>

Now what I am trying to do here is setting a Click Command in my ViewModel, Usually, how I did that was setting a name to the ListView as I have in the above example and then use this name to get the List's BindingContext and then use this to set the command to it, but when I try to use this now it throws an XML parser exception:

Xamarin.Forms.Xaml.XamlParseException: Position 38:43. Can not find the object referenced by HomeList

Now I have two questions:

1- What is the correct way of setting a command to the ListView when doing it the above way?

2- If in the future I plan on moving this to App.XAML(if used multiple times) how can I set the command to it then?

Upvotes: 0

Views: 655

Answers (1)

pvsfair
pvsfair

Reputation: 320

Sorry about the misleading link, I understood your problem just now.

You could use the ListView Behaviors to solve your problem, it's so fancy and easier to reader than bind the command on the code behind.

You could follow the link below to see how it's done, and later make it better just converting all the behaviors into only one and passing a event name to it, looking for the event with GetRuntimeEvent(eventName) and AddEventHandler() on the object that the last method returns.

In the end your list view would look something like this:

<ListView HasUnevenRows = "true" ItemsSource="{Binding CurrentTripInfo}" BackgroundColor="Transparent"
       CachingStrategy="RecycleElement" x:Name="HomeList" SeparatorVisibility ="Default" Grid.Row="1" ItemTemplate="{StaticResource ListItemTemplate}" >
    <ListView.Behaviors>
        <behaviors:EventToCommand EventName="ItemTapped" Command="{Binding ClickCommand}"/>
    </ListView.Behaviors>
</ListView>

https://devblogs.microsoft.com/xamarin/turn-events-into-commands-behaviors/

Upvotes: 2

Related Questions