0
votes

I have a problem. I created this CollectionView with a few dummy trades, that looks like this right now: enter image description here

Now this is almost like I want it, except for 1 thing: I want the last column to get a rowspan over both the rows, like this: enter image description here

Now if this was a regular Grid, I could do it with Grid.RowSpawn, but it is in a CollectionView, because I can have a lot of trades. The downside of the CollectionView is that each row is a different Grid, so they are actually not connected! Here is my code right now:

<CollectionView ItemsSource="{Binding agentOrderList}" Margin="0" HeightRequest="450">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid RowSpacing="0">
                <StackLayout Orientation="Vertical">
                    <StackLayout HorizontalOptions="FillAndExpand" HeightRequest="1" BackgroundColor="White"/>
                    <Grid RowSpacing="0" Margin="5,0,5,0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="21" />
                            <RowDefinition Height="21" />
                            <RowDefinition Height="4" />
                        </Grid.RowDefinitions>

                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="65" />
                            <ColumnDefinition Width="95" />
                            <ColumnDefinition Width="40" />
                            <ColumnDefinition Width="75" />
                            <ColumnDefinition Width="82" />
                        </Grid.ColumnDefinitions>

                        <Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Text="{Binding Date}" FontAttributes="Bold" TextColor="#00D8FF" FontSize="18" VerticalOptions="CenterAndExpand"/>
                        <Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Text="{Binding Action}" TextColor="White" FontSize="18" VerticalOptions="CenterAndExpand"/>
                        <Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Text="{Binding Coin}" TextColor="White" FontSize="18" VerticalOptions="CenterAndExpand"/>
                        <Label Grid.Row="0" Grid.RowSpan="2" Grid.Column="3" Text="{Binding Price}" TextColor="White" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End"/>
                        <Label Grid.Row="0" Grid.Column="4" Text="{Binding ProfitUSDT}" TextColor="{Binding ProfitColor}" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End"/>
                        <Label Grid.Row="1" Grid.Column="4" Text="{Binding ProfitPerc}" TextColor="{Binding ProfitColor}" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="End"/>

                    </Grid>
                </StackLayout>
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Now what is the best way to achieve this? Do I need to make a different view? Please let me know!

1

1 Answers

1
votes

You can't have data cross over between cells in a ListView, so I think you will need to make each list item have a two row grid, so then you can have the last column span two rows.

However, I am confused. Your XAML code does not seem to match the screen shot of one cell. Your XAML code only seems to assign 5 columns, but I see 6 in your screen shots?

IN any case, you are correct, you will need to use one grid to display the Buy and Sell data so that that last column can span 2 rows.

UPDATE: Based on comments below, it seems a DataTemplateSelector may be required here. See: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/selector

Partial extract from above link:

A data template selector enables scenarios such as a ListView binding to a collection of objects, where the appearance of each object in the ListView can be chosen at runtime by the data template selector returning a particular DataTemplate.

Creating a DataTemplateSelector A data template selector is implemented by creating a class that inherits from DataTemplateSelector. The OnSelectTemplate method is then overridden to return a particular DataTemplate, as shown in the following code example:

public class PersonDataTemplateSelector : DataTemplateSelector
{ 
    public DataTemplate ValidTemplate { get; set; }
    public DataTemplate InvalidTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
    {
        return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;   
     } 
 }

The OnSelectTemplate method returns the appropriate template based on the value of the DateOfBirth property. The template to return is the value of the ValidTemplate property or the InvalidTemplate property, which are set when consuming the PersonDataTemplateSelector.

An instance of the data template selector class can then be assigned to Xamarin.Forms control properties such as ListView.ItemTemplate. For a list of valid properties, see Creating a DataTemplate.

Limitations

DataTemplateSelector instances have the following limitations:

  • The DataTemplateSelector subclass must always return the same template for the same data if queried multiple times.
  • The DataTemplateSelector subclass must not return another DataTemplateSelector subclass.
  • The DataTemplateSelector subclass must not return new instances of a DataTemplate on each call. Instead, the same instance must be returned. Failure to do so will create a memory leak and will disable virtualization.
  • On Android, there can be no more than 20 different data templates per ListView.

Consuming a DataTemplateSelector in XAML

In XAML, the PersonDataTemplateSelector can be instantiated by declaring it as a resource, as shown in the following code example:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Selector;assembly=Selector" x:Class="Selector.HomePage">
 <ContentPage.Resources>
     <ResourceDictionary>
         <DataTemplate x:Key="validPersonTemplate">
             <ViewCell>
                ...
             </ViewCell>
         </DataTemplate>
         <DataTemplate x:Key="invalidPersonTemplate">
             <ViewCell>
                ...
             </ViewCell>
         </DataTemplate>
         <local:PersonDataTemplateSelector x:Key="personDataTemplateSelector"
             ValidTemplate="{StaticResource validPersonTemplate}"
             InvalidTemplate="{StaticResource invalidPersonTemplate}" />
     </ResourceDictionary>
 </ContentPage.Resources>   
    ... 
</ContentPage> 

This page level ResourceDictionary defines two DataTemplate instances and a PersonDataTemplateSelector instance. The PersonDataTemplateSelector instance sets its ValidTemplate and InvalidTemplate properties to the appropriate DataTemplate instances by using the StaticResource markup extension. Note that while the resources are defined in the page's ResourceDictionary, they could also be defined at the control level or application level.

The PersonDataTemplateSelector instance is consumed by assigning it to the ListView.ItemTemplate property, as shown in the following code example:

<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" /> 

At runtime, the ListView calls the PersonDataTemplateSelector.OnSelectTemplate method for each of the items in the underlying collection, with the call passing the data object as the item parameter. The DataTemplate that is returned by the method is then applied to that object.