Skip to content

Binding the Swipe command in a SwipeView within a CollectionView template won't work in .NET 10 RC2. #32332

@kaniosm

Description

@kaniosm

Description

Binding the Swipe command in a SwipeView within a CollectionView template won't work in .NET 10 RC2.

See sample below:

<CollectionView Grid.Row="2"
                Grid.ColumnSpan="3"
                x:Name="CustomersListView"
                ItemsSource="{Binding Customers}"
                SelectionMode="Single"
                SelectedItem="{Binding SelectedCustomer}">
	<CollectionView.ItemsLayout>
		<GridItemsLayout x:Name="ItemsListItemsLayout"
		                 Span="{x:OnIdiom Tablet=2, Phone=1}"
		                 Orientation="Vertical"/>
	</CollectionView.ItemsLayout>
	<CollectionView.ItemTemplate>
		<DataTemplate x:DataType="models:Customer">
			<SwipeView x:Name="SwipeView1">
				<Border x:Name="SwipeBorder"
				        Padding="8"
				        Stroke="LightGray"
				        BackgroundColor="{Binding BackgroundColor, Source={x:Reference SwipeView1}, x:DataType={x:Type SwipeView}}">
					<Grid RowDefinitions="Auto,Auto,Auto">
						<Label x:Name="LabelCode"
						       Grid.Row="0"
						       Text="{Binding Name}"
						       LineBreakMode="WordWrap"
						       TextColor="Black"
						       FontAttributes="Bold"/>
						<Label x:Name="LabelName"
						       Grid.Row="1"
						       TextColor="Black">
							<Label.FormattedText>
								<FormattedString>
									<Span Text="{Binding Code}"
									      TextColor="{Binding TextColor, Source={x:Reference LabelName}, x:DataType={x:Type Label}}"/>
									<Span Text="{Binding Area.AreaName, StringFormat='{} - {0}'}"
									      TextColor="{Binding TextColor, Source={x:Reference LabelName}, x:DataType={x:Type Label}}"/>
									<Span Text="{Binding Telephone, StringFormat='{} - {0}'}"
									      TextColor="{Binding TextColor, Source={x:Reference LabelName}, x:DataType={x:Type Label}}"/>
								</FormattedString>
							</Label.FormattedText>
						</Label>
						<Label x:Name="LabelContact"
						       Grid.Row="2"
						       Text="{Binding Contact, StringFormat='{}Contact: {0}'}"
						       TextColor="Black"/>
					</Grid>
				</Border>
				<SwipeView.RightItems>
					<SwipeItems Mode="Reveal">
						<SwipeItem BackgroundColor="#6279B8"
						           Command="{Binding NewOrderCommand, Source={x:RelativeSource AncestorType={x:Type vms:CustomersViewModel}}, x:DataType={x:Type vms:CustomersViewModel}}"
						           CommandParameter="{Binding .}"
						           Text="Ord"
						           IsVisible="{Binding AllowOrders, Source={x:RelativeSource AncestorType={x:Type vms:CustomersViewModel}}, x:DataType={x:Type vms:CustomersViewModel}}"/>
					</SwipeItems>
				</SwipeView.RightItems>
			</SwipeView>
		</DataTemplate>
	</CollectionView.ItemTemplate>
</CollectionView>

Steps to Reproduce

  1. Create a new MAUI app
  2. New Page bound to a ViewModel
  3. Add an ObserbableCollection to a class and bind it to a CollectionView
  4. Add a SwipeView in the template of the CollectionView with a command binding to a command in the viewmodel (not the data item from the list)
  5. Debug in Android and try to execute the command after swiping an entry

Link to public reproduction project repository

No response

Version with bug

10.0.0-rc.2

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

No response

Affected platforms

Android

Affected platform versions

Tested with Android emulator API 33 and a a Physical Android device API 35

Did you find any workaround?

  1. Implement the invoke command event in the page code behind section.
<SwipeItems>
    <SwipeItem BackgroundColor="Red" Invoked="SwipeItem_Invoked" Text="Delete"/>
</SwipeItems>

private async void SwipeItem_Invoked(object sender, EventArgs e)
{
    if (sender is SwipeItem s && s.BindingContext is Customer c)
    {

    }
}

  1. Expose my view model through a static resource, and bind through the resource rather using RelativeSource and AncestorType.
    public class ViewModelLocator { public CustomersViewModel Customers => App.Services.GetRequiredService<CustomersViewModel>(); }

In App.xaml:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
            <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            <ResourceDictionary Source="Resources/Styles/AppStyles.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <vms:ViewModelLocator x:Name="Locator" x:Key="Locator" x:FieldModifier="public" />
    </ResourceDictionary>
</Application.Resources>

In my page:


<SwipeItem BackgroundColor="LightGreen" Command="{Binding Customers.NewOrderCommand, Source={StaticResource Locator},
                x:DataType={x:Type vms:ViewModelLocator}}" CommandParameter="{Binding .}" Text="Ord" />

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions