I have been at this for several days. Please show me my dumb error. I have even dumbed down my code to just about match the example in this article with no luck. (https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/collectionview/populate-data?view=net-maui-9.0) Example from Article;
<CollectionView x:Name="collectionView"
ItemsSource="{Binding Monkeys}">
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Favorite"
IconImageSource="favorite.png"
BackgroundColor="LightGreen"
Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
CommandParameter="{Binding}" />
<SwipeItem Text="Delete"
IconImageSource="delete.png"
BackgroundColor="LightPink"
Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
CommandParameter="{Binding}" />
</SwipeItems>
</SwipeView.LeftItems>
<Grid BackgroundColor="White"
Padding="10">
<!-- Define item appearance -->
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
I am having multiple issues based upon what different method to solve my issue I try.. But ultimately my issue is that I cannot get the swipeview properly implemented where its command binds to the RelayCommand in my viewmodel and the commandparameter binds to the type of Model. No matter what I have tried, the swipeviews bindingcontext is ALWAYS of type Model.. I will try to provide as much relevant info as I can.
Below is my xaml page, not sure if all of it is helpful but I dont want to hinder your help.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:LoanShark.ViewModels"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:custom="clr-namespace:LoanShark.Behaviors"
xmlns:model="clr-namespace:LoanShark.Models"
xmlns:repo="clr-namespace:LoanShark.Data.Repositories"
xmlns:local="clr-namespace:LoanShark.Views"
x:Class="LoanShark.Views.LoanPage"
x:Name="Loan_Page"
x:DataType="vm:LoanViewModel"
Title="Loans">
<Grid>
<!-- Main Content -->
<!-- Show message when Loans is empty -->
<Label Text="No loans found."
IsVisible="{Binding Loans.Count, Converter={StaticResource IsZeroConverter}}"
HorizontalOptions="Center"
VerticalOptions="Center" />
<!--Loan List-->
<CollectionView x:Name="loansCollectionView"
ItemsSource="{Binding Loans}"
VerticalOptions="FillAndExpand">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Loan">
<SwipeView BindingContext="{Binding .}">
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="Edit"
BackgroundColor="LightGray"/>
<SwipeItem Text="Delete"
BackgroundColor="LightPink"
Command="{Binding Source={x:Reference loansCollectionView}, Path=BindingContext.DeleteLoanCommand}"
CommandParameter="{Binding .}" >
<SwipeItem.BindingContext>
<model:Loan/>
</SwipeItem.BindingContext>
</SwipeItem>
</SwipeItems>
</SwipeView.LeftItems>
<Border x:Name="LoanBorder">
<Border.GestureRecognizers>
<TapGestureRecognizer Tapped="OnExpandButtonClicked"
NumberOfTapsRequired="1"/>
</Border.GestureRecognizers>
<Border.Behaviors>
<toolkit:TouchBehavior BindingContext="{Binding Path=BindingContext, Source={x:Reference LoanBorder}, x:DataType=Border}"
LongPressCommand="{Binding Source={x:Reference Loans}, Path=BindingContext.ShowContextMenuCommand, x:DataType=ContentPage}"
LongPressCommandParameter="{Binding .}"
LongPressDuration="1500"/>
</Border.Behaviors>
<VerticalStackLayout x:Name="LoansStackLayout"
x:DataType="model:Loan">
<!--Default View-->
<Label Text="{Binding Borrower.FullName}"
Style="{DynamicResource SubHeaderLabelStyle}"
FontSize="16" />
<!--Collapsible Details-->
<toolkit:Expander x:Name="LoanExpander"
IsExpanded="{Binding IsExpanded, Mode=TwoWay}"
ExpandedChanged="OnExpanderToggled" >
<toolkit:Expander.Header>
<Grid ColumnDefinitions="*, Auto"
VerticalOptions="CenterAndExpand">
<Label Text="{Binding Name}"
Style="{DynamicResource RegularLabelStyle}"
FontSize="14"
Grid.Column="0" />
<!--Chevron Icon-->
<Image x:Name="ChevronIcon"
Source="up_chevron.svg"
WidthRequest="24"
HeightRequest="24"
Grid.Column="1"
RotationX="180"
VerticalOptions="Center">
</Image>
</Grid>
</toolkit:Expander.Header>
<toolkit:Expander.Content>
<Grid RowDefinitions="Auto, Auto, Auto, Auto" ColumnDefinitions="*, Auto">
<!--Original Loan Amount-->
<Label Text="Original:" Style="{DynamicResource SubHeaderLabelStyle}" Grid.Row="0" Grid.Column="0" />
<Label Text="{Binding OriginalLoanAmount, StringFormat='{0:C}'}"
Style="{DynamicResource RegularLabelStyle}" Grid.Row="0" Grid.Column="1" HorizontalOptions="End" />
<!--Remaining Loan Amount-->
<Label Text="Remaining:" Style="{DynamicResource SubHeaderLabelStyle}" Grid.Row="1" Grid.Column="0" />
<Label Text="{Binding RemainingLoanAmount, StringFormat='{0:C}'}"
Style="{DynamicResource RegularLabelStyle}" Grid.Row="1" Grid.Column="1" HorizontalOptions="End" />
<!--Interest Rate-->
<Label Text="Interest Rate:" Style="{DynamicResource SubHeaderLabelStyle}" Grid.Row="2" Grid.Column="0" />
<Label Text="{Binding Interest, StringFormat='{0:P}'}"
Style="{DynamicResource RegularLabelStyle}" Grid.Row="2" Grid.Column="1" HorizontalOptions="End" />
<!--Loan End Date-->
<Label Text="End Date:" Style="{DynamicResource SubHeaderLabelStyle}" Grid.Row="3" Grid.Column="0" />
<Label Text="{Binding LoanEndDate, StringFormat='{0:MM/dd/yyyy}'}"
Style="{DynamicResource RegularLabelStyle}" Grid.Row="3" Grid.Column="1" HorizontalOptions="End" />
</Grid>
</toolkit:Expander.Content>
</toolkit:Expander>
</VerticalStackLayout>
</Border>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<!-- Floating Add Button -->
<Button Text="+"
Command="{Binding NavigateToNewLoanCommand}"
HorizontalOptions="End"
VerticalOptions="End"
Style="{DynamicResource FloatingActionButtonStyle}" />
</Grid>
I have exhausted all the options I can possibly come up with myself. I tried removing the x:Datatype model:Loan from the DataTemplate and putting it in the nested verticalstacklayout, that helped for the command binding but the commandparameter I could never get. Event with this option, I could not simply make the command "{Binding DeleteLoanCommand}" I still had to provide a somewhat complex binding of Command="{Binding Source={RelativeSource AncestorType={x:Type vm:LoanViewModel}}, Path=DeleteLoanCommand}"
Putting the x:DataType back on the DataTemplate makes the command never fire no matter how I structure the binding.
the viewmodel has a RelayCommand called DeleteLoanAsync which the communitytoolkit.mvvm converts to a command under the hood and renames it to DeleteLoanCommand
One last thing.... I will greatly appreciate any help on this, but also any resources or tips n tricks to gain a better understanding into bindings you think would help I will gladly read, I thought I knew and understood bindings but this one has me second guessing myself.
LoanPageand the code forLoanViewModel?