Search code examples
.netxamlxamarin.formsmaui

Using TouchEffect with a Button in Xamarin Forms / .NET MAUI


I have CollectionView with several items.

The items have same datatemplate, which consists of a stacklayout with a button.

    <CollectionView ItemSizingStrategy="MeasureFirstItem"
                    ItemsSource="{Binding SaveItems}"
                    SelectionMode="None">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="listItems:MyItemVM">
                <StackLayout TouchEffect.Command="{Binding SelectedItemCommand}"
                             TouchEffect.CommandParameter="{Binding .}">
                    <Button Command={Binding OnCreateCommand} CommandParameter={Binding .} />
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

When I press the Button, the Stacklayout is invoked instead, because it is higher in view hierarchy. How do I make it so I press outside the button it invokes the StackLayout command, and if I press the button is invokes the button command ?

I have tried multiple settings with InputTransparent, CascadeInputTransparent, TouchEffect.ShouldMakeChildrenInputTransparent. I was expecting that InputTransparent = true resulted in both commands working but no. With InputTransparent = true either one works and the other doesn't, or vice-versa.

I have thought about using Skia renderer to detect touch position, or intercepting touch event in native code, but I hope there is an easier way with XAML.

EDIT: I managed to detect both commands with the following datatemplate:

<StackLayout>
  <Grid>
    <Grid TouchEffect.Command="{Binding SelectedItemCommand}"
                             TouchEffect.CommandParameter="{Binding .}" /> 
    <Grid>
         <Button Command={Binding OnCreateCommand} CommandParameter={Binding .} />
    </Gri>
  </Grid>
</StackLayout>

Because Grid content can overlay. It is not very performant but it works.


Solution

  • SOLVED: I managed to detect both commands with the following datatemplate:

    <StackLayout>
      <Grid>
        <Grid TouchEffect.Command="{Binding SelectedItemCommand}"
                                 TouchEffect.CommandParameter="{Binding .}" /> 
        <Grid>
             <Button Command={Binding OnCreateCommand} CommandParameter={Binding .} />
        </Gri>
      </Grid>
    </StackLayout>
    

    Because Grid content can overlay. It is not very performant but it works.