xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.63k stars 1.88k forks source link

[Bug] Button click events cut off by Grid edges when translating it outside Grid cell bounds #6760

Open aormsby opened 5 years ago

aormsby commented 5 years ago

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.

Further Remarks:

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

Video Reproduction

video_GridTranslationBug.zip

Reproduction Link

GridTranslation_Bug.zip

jfversluis commented 5 years ago

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,

kimbirkelund commented 4 years ago

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.

jfversluis commented 4 years ago

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

kimbirkelund commented 4 years ago

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.