Xamarin.forms: [Bug] Button click events cut off by Grid edges when translating it outside Grid cell bounds

Created on 3 Jul 2019  ·  4Comments  ·  Source: xamarin/Xamarin.Forms

Description

Translating a Button view outside the edges of a Grid cell cuts off the 'Clicked' event bounds. The event bounds do translate with the Button properly, but the event does not function outside of the Grid cell it's placed in. I can click on the parts of the Button inside the parent Grid cell, but I can't click on the parts outside of the cell bounds.

This is shown in the solution file I attached. There's also a video.

  • The left side Button is in Grid row 0 and uses TranslationY="40" to push it outside the bottom of its cell. It is obscured by row 1. (I think this is expected behavior, but I'm not sure.)
  • The right side Button is in Grid row 1 and uses TranslationY="-40" to push it outside the top of its cell. It is not obscured visually, which I would expect in this case. However I am unable to trigger the click event on the top portion of the Button.

Further Remarks:

  • I'm inclined to think this is an issue with Grid (not Button), because the issue also occurred when I tried it with a Slider view. I couldn't click and slide it when outside its parent Grid cell.
  • It doesn't seem to be platform-specific or device-specific as the bug occurs on both Android and iOS

Steps to Reproduce

  1. Open solution file GridTranslation_Bug.
  2. Build and Run the program on an Android simulator (or iOS).
  3. Try to click both buttons inside and outside of their parent Grid cells.
  4. Check the Console output for click events (I added a counter). Events will only register when Button is clicked inside its parent Grid cell's bounds.

Expected Behavior

I should be able to use translation to move the Button outside its parent view and still trigger the click event by clicking anywhere within the button bounds.

Actual Behavior

In the translated Button, only the Button space within the bounds of the parent Grid cell is clickable. Outside of the Grid bounds, the Button does not receive a click event.

Basic Information

  • Version with issue: Xamarin.Forms (4.1.0.555618)
  • Last known good version: ???
  • IDE: Visual Studio for Mac Community 8.1.3 (build 19)
  • Platform Target Frameworks:

    • iOS: 12.2

    • Android: API 28

  • Nuget Packages: Project defaults

    • Xamarin.Essentials (1.1.0)

    • Xamarin.Forms (4.1.0.555618)

  • Affected Devices: Android, iOS

Video Reproduction

video_GridTranslationBug.zip

Reproduction Link

GridTranslation_Bug.zip

grid 5 help wanted Android iOS 🍎 bug up-for-grabs

Most helpful comment

While I haven't found a proper workaround it turned the ControlTemplate didn't actually exacerbate the problem. So I was able to solve it by combining negative margin with positive padding like so:

<ContentPage
    x:Class="App5.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Name="Root"
    mc:Ignorable="d">

    <ContentPage.ControlTemplate>
        <ControlTemplate>
            <Grid BackgroundColor="Red">

                <!-- Use Padding here, as Margin breaks it -->
                <ContentPresenter Padding="0,50,0,0" />

                <Label
                    Margin="10"
                    BackgroundColor="Green"
                    FontSize="Title"
                    HorizontalOptions="Fill"
                    HorizontalTextAlignment="Center"
                    Text="{Binding Text, Source={x:Reference Root}}"
                    VerticalOptions="End" />
            </Grid>

        </ControlTemplate>
    </ContentPage.ControlTemplate>

    <!-- The Margin and Padding here cancels each other out, 
         but ensure that the bounds of the Grid expands upwards. -->
    <Grid
        Margin="0,-50,0,0"
        Padding="0,50,0,0"
        BackgroundColor="Aqua">

        <Button
            Clicked="Button_OnClicked"
            HeightRequest="50"
            Text="Klik"
            TranslationY="-50"
            VerticalOptions="Start" />

    </Grid>
</ContentPage>

The important part is the fact that Margin is used on the Grid the expand it to fill more than is actually needed and Padding is then used to fix the positioning (where Margin would normally be more apt).

While it won't work for everything it was actually a lot easier in my case than I feared.

All 4 comments

I’ve been able to reproduce this. I had a hunch (or hope…) that with the InputTransparent="True" on the Grid I could manage to get this working, but alas.

Also does not work when you replace the Grid with a StackLayout, so I think it is a general thing with overlapping layout items,

I've the same issue, and it is quite critical as I can't easily change the layout to avoid it (the page has a ControlTemplate and I'm translating the button outside the pages bounds, into the ControlTemplate area).

How you found a workaround or something?

I've tried with an AbsoluteLayout and that appears to have the same issue.

Unfortunately, I did not find any workaround. If you do, it would be great if you could share it here!

While I haven't found a proper workaround it turned the ControlTemplate didn't actually exacerbate the problem. So I was able to solve it by combining negative margin with positive padding like so:

<ContentPage
    x:Class="App5.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Name="Root"
    mc:Ignorable="d">

    <ContentPage.ControlTemplate>
        <ControlTemplate>
            <Grid BackgroundColor="Red">

                <!-- Use Padding here, as Margin breaks it -->
                <ContentPresenter Padding="0,50,0,0" />

                <Label
                    Margin="10"
                    BackgroundColor="Green"
                    FontSize="Title"
                    HorizontalOptions="Fill"
                    HorizontalTextAlignment="Center"
                    Text="{Binding Text, Source={x:Reference Root}}"
                    VerticalOptions="End" />
            </Grid>

        </ControlTemplate>
    </ContentPage.ControlTemplate>

    <!-- The Margin and Padding here cancels each other out, 
         but ensure that the bounds of the Grid expands upwards. -->
    <Grid
        Margin="0,-50,0,0"
        Padding="0,50,0,0"
        BackgroundColor="Aqua">

        <Button
            Clicked="Button_OnClicked"
            HeightRequest="50"
            Text="Klik"
            TranslationY="-50"
            VerticalOptions="Start" />

    </Grid>
</ContentPage>

The important part is the fact that Margin is used on the Grid the expand it to fill more than is actually needed and Padding is then used to fix the positioning (where Margin would normally be more apt).

While it won't work for everything it was actually a lot easier in my case than I feared.

Was this page helpful?
0 / 5 - 0 ratings