0
votes

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?

1
@Nirmal Subedi Not a duplicate. Look at both posts. For one, I'm trying to do this exclusively in XAML. For another, it covers creating a DatatemplateSelector, which my code already does. My question is one of creating a more efficient solution.Russ
If you have 2 different views based on odd/even rows then it makes more sense to create DataTemplate for them but just for making "only the alternate background color", i do not recommend doing that using 2 different datatemplate!Nirmal Subedi
@Nirmal Subedi. You're not helping--reread my post completely. Your recommendation is exactly what I asking about, and I discuss the issue I ran into. I imagine it's probably a simple thing I'm missing.Russ
I misunderstood your question, So instead defining your Grid in same page XAML, you can create that as an new object then reference that wherever you want. See the below answer and make corrections if you need to. Let me know if you need more helpNirmal Subedi

1 Answers

2
votes

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.