Skip to content

[Android] Upgrade to 10.0.90 does not handle UI events properly #36942

Closed

Description

@bebenlebricolo

Description

In my Android app, I noticed that new UI-related bugs appeared right after upgrading MAUI.Controls (and Compat) from 10.0.80 to 10.0.90.

Here are 2 small clips showcasing the behavior change:

MAUI 10.0.80 - events are propagated correctly

10.0.80-events-propagation-ok-cropped.mp4

MAUI 10.0.90 - events are not propagated correctly to the UI (internal boolean properties is OK, but visual state only updates when toggling the parent section - toggles between Enabled/Disabled).

10.0.90-events-propagation-ko-cropped.mp4

Steps to Reproduce

A template project would be nice to write, I don't have the bandwidth to do so right now, I'll try to come up with a small repro project in few weeks.
Meanwhile, I think we could investigate the changes around event propagation.

My current hypotheses (potentially wrong indeed) are hovering around UI state propagation and event handling.
I also noticed that introducing breakpoints (while debugging) helped and within Android emulators and physical devices, having breakpoints will delay the process just enough for visual states to be updated correctly (hence why I describe it as "event storm" -> I believe some events are dropped/lost and that might be why the UI is not updating.

A strong pointer to this hypothesis is the fact that the parent section toggle switch (bound to the Enabled property of the Border control) re-triggers visual state update and it is enough to make the UI respond.

Note: I cannot update the code pages because Github won't let me update xaml pages.

<!-- Date filter -->
                        <Border Grid.Row="0"
                                x:Name="DateFilterBorder"
                                Stroke="{AppThemeBinding Light=#55111111, Dark=#55999999}"
                                StrokeShape="RoundRectangle 20"
                                StrokeThickness="1"
                                Padding="5">
                            <Grid RowDefinitions="auto,auto,auto,auto,auto"
                                  RowSpacing="0">

                                <!-- Top part of the Date filter block -->
                                <Grid Grid.Row="0"
                                      ColumnDefinitions="auto,auto,*,auto"
                                      MaximumHeightRequest="30">
                                    <Switch Grid.Column="0"
                                            x:Name="DateSwitch"
                                            IsToggled="{Binding DateFilterEnabled}" />
                                    <Label Grid.Column="1"
                                           Text="Date"
                                           IsEnabled="{Binding DateFilterEnabled}"
                                           VerticalOptions="Center" />
                                    <Border Grid.Column="3"
                                            Stroke="Transparent"
                                            BackgroundColor="#555555"
                                            StrokeShape="RoundRectangle 30"
                                            HeightRequest="20"
                                            WidthRequest="20"
                                            Margin="10"
                                            Padding="5"
                                            HorizontalOptions="Start">
                                        <Image Source="appinfo_icon.svg" />
                                        <Border.GestureRecognizers>
                                            <TapGestureRecognizer x:Name="DateInfoTapGesture"
                                                                  Command="{Binding ShowDateFilterHelpCommand}" />
                                        </Border.GestureRecognizers>
                                    </Border>
                                </Grid>

                                <!-- Future-ish events filter -->
                                <Grid Grid.Row="1" ColumnDefinitions="auto,auto,auto,auto"
                                      Margin="20,0,5,0"
                                      ColumnSpacing="10"
                                      IsEnabled="{Binding DateFilterEnabled}"
                                      MaximumHeightRequest="40">
                                    <controls:TextSwitch Grid.Column="0"
                                                         Text="Futurs"
                                                         Activated="{Binding FutureDateFilterEnabled}" />
                                    <controls:TextSwitch Grid.Column="1"
                                                         Text="Semaine"
                                                         Activated="{Binding ThisWeekFilterEnabled}" />
                                    <controls:TextSwitch Grid.Column="2"
                                                         Text="Mois"
                                                         Activated="{Binding ThisMonthFilterEnabled}" />
                                    <controls:TextSwitch Grid.Column="3"
                                                         Text="Année"
                                                         Activated="{Binding ThisYearFilterEnabled}" />
                                </Grid>

                                <!-- Custom date events filtering -->
                                <Grid Grid.Row="3" ColumnDefinitions="*,*"
                                      Margin="20,0,5,0"
                                      ColumnSpacing="10"
                                      IsEnabled="{Binding DateFilterEnabled}">
                                    <controls:TextSwitch Grid.Column="0"
                                                         Text="Manuelle"
                                                         Activated="{Binding CustomDateFilterEnabled}" />
                                    <Grid Grid.Column="1" RowDefinitions="*,*"
                                          ColumnSpacing="10"
                                          HorizontalOptions="End"
                                          IsEnabled="{Binding CustomDateFilterEnabled}">
                                        <Grid Grid.Row="0"
                                              ColumnDefinitions="auto,*"
                                              ColumnSpacing="10">
                                            <Label Grid.Column="0"
                                                   Text="Début"
                                                   VerticalOptions="Center" />
                                            <Border Grid.Column="1"
                                                    Stroke="Transparent"
                                                    StrokeShape="RoundRectangle 20"
                                                    MaximumHeightRequest="40"
                                                    BackgroundColor="Transparent"
                                                    HorizontalOptions="End">
                                                <DatePicker VerticalOptions="Center"
                                                            HorizontalOptions="Center"
                                                            Margin="10,0"
                                                            Date="{Binding CustomStartDate}" />
                                            </Border>
                                        </Grid>
                                        <Grid Grid.Row="1"
                                              ColumnDefinitions="auto,*"
                                              ColumnSpacing="10">
                                            <Label Grid.Column="0"
                                                   Text="Fin"
                                                   VerticalOptions="Center" />
                                            <Border Grid.Column="1"
                                                    Stroke="Transparent"
                                                    StrokeShape="RoundRectangle 20"
                                                    MaximumHeightRequest="40"
                                                    BackgroundColor="Transparent"
                                                    HorizontalOptions="End">
                                                <DatePicker VerticalOptions="Center"
                                                            HorizontalOptions="Center"
                                                            Margin="10,0"
                                                            Date="{Binding CustomEndDate}" />
                                            </Border>
                                        </Grid>
                                    </Grid>
                                </Grid>


                            </Grid>
                        </Border>

The code-behind page is totally trivial (default implementation).
And here is a sample of what the ViewModel looks like:

public partial class EventListFilterViewModel : ObservableObject
{
    #region Date Filter Properties

    [ObservableProperty] private bool _dateFilterEnabled = true;

    // Future filter, this is the default state of the query (reproduces the default website behavior)
    [ObservableProperty] private bool _futureDateFilterEnabled = true;

    // Past Filters
    [ObservableProperty] private bool _thisWeekFilterEnabled = false;
    [ObservableProperty] private bool _thisMonthFilterEnabled = false;
    [ObservableProperty] private bool _thisYearFilterEnabled = false;

    // Custom Date Filters
    [ObservableProperty] private bool _customDateFilterEnabled = false;
    [ObservableProperty] private DateTime _customStartDate = DateTime.Now.AddYears(-1);
    [ObservableProperty] private DateTime _customEndDate = DateTime.Now;

    partial void OnFutureDateFilterEnabledChanged(bool value)
    {
        if(value && ThisWeekFilterEnabled)
        {
            ThisWeekFilterEnabled = false;
        }

        if (value && ThisMonthFilterEnabled)
        {
            ThisMonthFilterEnabled = false;
        }

        if (value && ThisYearFilterEnabled)
        {
            ThisYearFilterEnabled = false;
        }

        else if(value && CustomDateFilterEnabled)
        {
            CustomDateFilterEnabled = false;
        }
    }

    partial void OnThisWeekFilterEnabledChanged(bool value)
    {
        if (value && FutureDateFilterEnabled)
        {
            FutureDateFilterEnabled = false;
        }

        if (value && ThisMonthFilterEnabled)
        {
            ThisMonthFilterEnabled = false;
        }

        if (value && ThisYearFilterEnabled)
        {
            ThisYearFilterEnabled = false;
        }

        if (value && CustomDateFilterEnabled)
        {
            CustomDateFilterEnabled = false;
        }
    }

    partial void OnThisMonthFilterEnabledChanged(bool value)
    {
        if (value && FutureDateFilterEnabled)
        {
            FutureDateFilterEnabled = false;
        }

        if (value && ThisWeekFilterEnabled)
        {
            ThisWeekFilterEnabled = false;
        }

        if (value && ThisYearFilterEnabled)
        {
            ThisYearFilterEnabled = false;
        }

        if (value && CustomDateFilterEnabled)
        {
            CustomDateFilterEnabled = false;
        }
    }
// ...
}

As you may notice, the ViewModel overrides the CommunityToolkit-generated handlers and hooks up custom logic to update the ObservableProperties.

=> In the logic, you'll notice that;

  • When you update one property state (say, FutureDateFilterEnabled), it'll exclude the other properties and revert them back to false.
    This is meant to implement a mutually-exclusive pattern, where only a single visual state can remain.

Link to public reproduction project repository

No response

Version with bug

10.0.90

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

10.0.80

Affected platforms

Android

Affected platform versions

No response

Did you find any workaround?

Remaining on 10.0.80 ... Or find a way to rewrite the logic in the control itself, to circumvent the UI Properties not being well-transferred.

Relevant log output

Activity

  1. added
    potential-regressionThis issue described a possible regression on a currently supported version., verification pending
    on Jul 30, 2026
  2. Ahamed-Ali commented on Jul 30, 2026

    @Ahamed-Ali
    Contributor

    Based on the provided information, I have created a sample, but I am unable to reproduce the issue. Could you please provide a reproduction sample or modify the sample below to reproduce the issue? This would help us investigate the issue more quickly.

    Screen.Recording.2026-07-30.at.6.23.05.PM.mov

    Issue36942 (1).zip

  3. added
    s/needs-infoIssue needs more info from the author
    s/needs-reproAttach a solution or code which reproduces the issue
    on Jul 30, 2026
  4. bebenlebricolo commented on Jul 31, 2026

    @bebenlebricolo
    Author

    Excellent, thanks @Ahamed-Ali .
    I've put together a small bug repro repository and I managed to narrow the issue down to being triggered by a Border Shadow !
    In the sample code I gave you earlier, the main Border was missing (as it is a modal popup page, I wanted a shadow around the main border and thought it was not relevant to the issue itself.)

    Here in this screencast, you'll see that using Hot Reload (on Rider, but that should not affect the behavior), I could demonstrate that applying a shadow on the main border prevents proper UI event propagation/update.

    Capture.video.du.2026-07-31.10-42-19.mp4

    Here is the reproduction repository:
    MauiBug-10.0.90-BorderShadow-BreaksUIUpdates-Issue36942
    Note: maybe the Shadow behavior isn't the culprit here and it could be a combination of other issues, but at least I can reproduce the bug with a simple commented section, which is particularly handy 😄

    Let me know if you managed to reproduce the issue yourself !

  5. added
    s/needs-attentionIssue has more information and needs another look
    and removed
    s/needs-infoIssue needs more info from the author
    s/needs-reproAttach a solution or code which reproduces the issue
    on Jul 31, 2026
  6. NafeelaNazhir commented on Jul 31, 2026

    @NafeelaNazhir
    Contributor

    This issue has been validated in Visual Studio Code 1.130.0 with .NET MAUI versions 10.0.80 and 10.0.90. It can be reproduced on the Android platform from 10.0.90 version

    10.0.90(issue reproduced) 10.0.80(issue not reproduced)
    Screen.Recording.2026-07-31.at.2.36.21.PM.mov
    Screen.Recording.2026-07-31.at.2.38.59.PM.mov
  7. added
    s/verifiedVerified / Reproducible Issue ready for Engineering Triage
    s/triagedIssue has been reviewed
    i/regressionThis issue described a confirmed regression on a currently supported version
    and removed
    potential-regressionThis issue described a possible regression on a currently supported version., verification pending
    on Jul 31, 2026
  8. 6 remaining items

  9. added this to the .NET 10 SR10 milestone on Jul 31, 2026
  10. added 2 commits that reference this issue on Aug 3, 2026
    6e5b5dc
    5d428e5
  11. MohammadHoutari commented on Aug 13, 2026

    @MohammadHoutari

    Another manifestation of this 10.0.90 Android regression, from a shipped app — this one takes out a camera preview, and I think it argues for backporting #36988 to a 10.0.9x servicing release rather than waiting for SR10.

    Symptom

    A CameraX preview (BarcodeScanning.Native.Maui 3.0.6, which renders into a PreviewView in ImplementationMode.Compatible, i.e. a TextureView) hosted in a MAUI app on Android:

    MAUI Hosting Result
    10.0.80 CommunityToolkit Popup preview works
    10.0.90 CommunityToolkit Popup preview solid black
    10.0.90 Popup whose root Border has StrokeThickness="0" + Border.Shadow preview solid white
    10.0.90 plain ContentPage, no shadow preview renders, but frames go stale and freeze

    Microsoft.Maui.Controls was the only package changed between working and broken. Reproduced twice — reverting to 10.0.80 restored the preview, re-upgrading to 10.0.90 broke it again. Device: Xiaomi, Android 15.

    Why I am posting it here

    The white case is literally the pattern called out in #37279 and fixed by #36988 — a fully-transparent-stroke Border with a Shadow, with the affected content as a descendant:

    <Border x:Name="RootBorder" StrokeThickness="0" StrokeShape="RoundRectangle 24">
        <Border.Shadow>
            <Shadow Brush="Black" Offset="0,6" Radius="16" Opacity="0.3" />
        </Border.Shadow>
        ...
        <CameraView />   <!-- renders fully white on 10.0.90 -->

    And the described mechanism — software-canvas fallback clearing Android descendant dirty flags before the hardware pass, so stale display lists replay — matches a frozen camera preview more exactly than it matches a janky list. A TextureView invalidating 30 times a second is close to a worst case for "frequent descendant invalidations."

    One observation that may not fit

    Replacing the wrapping Border with a plain Grid — removing the Shadow, the rounded-corner clip, and with them the PlatformWrapperView entirely — did not restore the preview. The black and frozen-frame cases also occur with no shadow anywhere in the ancestor chain.

    So either the camera preview is a second, distinct regression in 10.0.90, or PlatformWrapperView is not the only invalidation path that #35623 affected. I would rather flag that honestly than assert a root cause I have not proven.

    Impact

    There is currently no released MAUI version with the fix — 10.0.90 is still the newest 10.0.x on NuGet, and #36988 is milestoned for SR10. For apps whose core workflow is barcode scanning, 10.0.90 is simply not adoptable, and the only option is to stay on 10.0.80 and forgo everything else in the release.

    If a backport of #36988 into a 10.0.9x servicing build is possible, it would unblock this class of app. I am happy to build a minimal repro (MAUI 10.0.90 + a TextureView-based camera preview, with and without a shadowed ancestor) if that would help triage.

  12. linked a pull request that will close this issueJuly 13th, Candidate #36411on Aug 25, 2026
  13. bebenlebricolo commented on Sep 4, 2026

    @bebenlebricolo
    Author

    Tested with 10.0.100 package version and I confirm this is fixed (at least for my use-case, this is a win. Thanks guys !)

  14. locked and limited conversation to collaborators on Oct 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-controls-generalGeneral issues that span multiple controls, or common base classes such as View or Elementi/regressionThis issue described a confirmed regression on a currently supported versionpartner/syncfusionIssues / PR's with Syncfusion collaborationplatform/androidregressed-in-10.0.90s/triagedIssue has been revieweds/verifiedVerified / Reproducible Issue ready for Engineering Triaget/bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions