Russ
Russ

Reputation: 4163

Xamarin Forms Binding layout with DataTemplateSelector

The code I have works, but it appears to me to be a kludgy cut-and-paste solution. I am looking for a more efficient way of coding the XAML so that the Grid does not need defined twice, but with a different background color

The code produces an alternating color background for rows of a ListView. This is a different issue from Alternate row color ListView xamarin forms.

A simplified example of my code:

<ContentPage.Resources>
    <DataTemplate x:Key="evenTemplate">
        <ViewCell>
            <Grid BackgroundColor="White" >
            <Label Text="{Binding Data}" />
            </Grid>
        </ViewCell>
    </DataTemplate>
    <DataTemplate x:Key="unevenTemplate">
        <ViewCell>
            <Grid BackgroundColor="Black" >
            <Label Text="{Binding Data}" />
            </Grid>
        </ViewCell>
    </DataTemplate>
    <local:AlternateColorDataTemplateSelector x:Key="alternateColorDataTemplateSelector"
            EvenTemplate="{StaticResource evenTemplate}"
            UnevenTemplate="{StaticResource unevenTemplate}" />
</ContentPage.Resources>
<ContentPage.Content>
    <ListView ItemTemplate="{StaticResource alternateColorDataTemplateSelector}" />
</ContentPage.Content>

The actual code is much more complicated than this. The problem is that using this design, I have two identical copies of the Grid, with the only difference being the background. The actual code winds up being around 23 lines of XAML duplicated, which causes a nightmare in maintainability--when one thing needs changed, I have to change it in two places (as you can see by the Label).

I tried defining the Grid outside the DataTemplate and binding it to the content of a ContentView, but then the controls inside the grid don't bind to my model (the BindingContext of the ContentPage). In other words, the Label no longer binds to Data. Example below:

<Grid x:Key="mainGrid" >
    <Label Text="{Binding Data}" />
</Grid>
<DataTemplate x:Key="evenTemplate">
    <ViewCell>
        <ContentView Content={StaticResource mainGrid}" BackgroundColor="White" />
    </ViewCell>
</DataTemplate>
<DataTemplate x:Key="evenTemplate">
    <ViewCell>
        <ContentView Content={StaticResource mainGrid}" BackgroundColor="Black" />
    </ViewCell>
</DataTemplate>

So, the question becomes, how do I do this, so that the Grid only needs defined once, but binds correctly and I have alternating row colors?

Upvotes: 0

Views: 1185

Answers (1)

NKR
NKR

Reputation: 2943

Im so sorry I misunderstood your problem. So you want to reuse the Grid code in viewcells in multiple places. For that, I would create a new Xaml file and put all my Contents for that grid in there like:

<Grid ... ... x:Class="TestProject.TestGrid">
   <Label Text="{Binding Name}"/>
</Grid>

Then In my DataTemplate:

<DataTemplate x:Key="evenTemplate">
<ViewCell>
    <ContentView BackgroundColor="White">
        <local:TestGrid />
    </ContentView>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="evenTemplate">
<ViewCell>
    <ContentView BackgroundColor="Black">
        <local:TestGrid />
    </ContentView>
</ViewCell>
</DataTemplate>

I have not tried this on my Visual Studio, I'm just typing. You might need to make corrections.

Upvotes: 2

Related Questions