Search code examples
c#maui

How can I show the total amount (by calculating the list items) in the collectionview group header by grouping date in .Net Maui


// My Main model of ExpensesDetailModel
public partial class ExpensesDetailModel : ObservableObject
{
    [PrimaryKey, AutoIncrement]
    public int ExpensesId { get; set; }
    public string? ExpensesDescription { get; set; }
    public double? Amount { get; set; }
    public DateTime ExpensesDate { get; set; } = DateTime.Now;
}
// My expenses group model inherits a List of ExpensesDetailModel
public class ExpensesGroupModel : List<ExpensesDetailModel>
{
    public DateTime ExpensesDate { get; set; }
    public ExpensesGroupModel(DateTime expensesDate, List<ExpensesDetailModel> expensesList) : base(expensesList)
    {
    ExpensesDate = expensesDate;
    }
}
// In my view model
// group the list by date
var dic = MonthlyExpensesList.GroupBy(x => x.ExpensesDate.Date).ToDictionary(d => d.Key, d => d.ToList());
foreach (KeyValuePair<DateTime, List<ExpensesDetailModel>> item in dic)
{
    MonthlyGroupExpensesList.Add(new ExpensesGroupModel(item.Key, new List<ExpensesDetailModel>(item.Value)));
}
<CollectionView Margin="10,8" ItemsSource="{Binding MonthlyGroupExpensesList}" IsGrouped="True">
    <CollectionView.GroupHeaderTemplate>
        <DataTemplate x:DataType="models:ExpensesGroupModel">
            <Frame Margin="0,5" Padding="10" HeightRequest="50" BorderColor="Transparent"
                BackgroundColor="Bisque">
                <HorizontalStackLayout>
                    <Label Text="{Binding ExpensesDate,StringFormat='{0:d}'}" FontSize="18"
                        TextColor="Black" FontAttributes="Bold" /> // I want to show the total
                    amount here <Label Text="{Binding Amount,StringFormat='{0:d}'}" />

                </HorizontalStackLayout>

            </Frame>
        </DataTemplate>
    </CollectionView.GroupHeaderTemplate>

    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="models:ExpensesDetailModel">
            <Frame Margin="0" Padding="10" CornerRadius="0">

                <VerticalStackLayout>

                    <HorizontalStackLayout HorizontalOptions="Start">
                        <Label Text="{Binding ExpensesDescription}" FontSize="16"
                            FontAttributes="Bold" />
                    </HorizontalStackLayout>

                    <HorizontalStackLayout HorizontalOptions="EndAndExpand">
                        <Label Margin="0,-25" Text="{Binding Amount,StringFormat='{0:n2}'}"
                            FontSize="18" FontAttributes="Bold" TextColor="Red" />
                    </HorizontalStackLayout>

                </VerticalStackLayout>
            </Frame>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

NOTE: From this code (from view model) I can show the list of items by grouping date

My expected result:

06/12/2024 Total: 60

Product A 10 Product B 20 Product C 30

07/12/2024 Total: 30

Product D 10
Product E 20

expected result Sample of expectation result


Solution

  • You can add a new property in your ExpensesGroupModel and calculate total amount for the group there.

    public class ExpensesGroupModel : List<ExpensesDetailModel>
    {
        public DateTime ExpensesDate { get; set; }
        public double Amount {get; set; }
        public ExpensesGroupModel(DateTime expensesDate, List<ExpensesDetailModel> expensesList) : base(expensesList)
        {
           ExpensesDate = expensesDate;
           Amount = expensesList.Where( x => x.Amount.HasValue).Sum( x => x.Amount.Value);
        }
    }