dotnet / dotnet/maui

[Android] Changing the style dynamically leaves the colors from the previous style

Open
#6,183 14 comments 1 reaction 0 assignees View on GitHub
area-xaml p/2 partner platform/android s/triaged s/verified t/bug
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

### Description

It seems this is a new issue related to the Release Candidate 1. When changing a style dynamically, that style can override any number of properties via its setters. The problem occurs when we have non-overlapping setters like in the following example:

```xml

<Setter Property="HeaderBackgroundColor" Value="LightGray" />

<Setter Property="HeaderTextColor" Value="LightPink" />
<Setter Property="HeaderBackgroundColor" Value="DarkRed" />

```

The first style changes the `HeaderBackgroundColor` property only, while the second one changes both the `HeaderTextColor` and `HeaderBackgroundColor` properties (check the attached project). When switching between these styles dynamically, the value of the `HeaderTextColor` property of the second style can affect the same property of the first style, even though the first style does not have a setter for that property. Similar behavior can be reproduced with just one style and `VisualStateManager` - to change a certain color based on the state of the control, when the base style does not define a value for that color.

This is rather unexpected and not consistent between the platforms. You can easily reproduce this behavior on Android (the color of the second style leaks to the first one), while it works differently on Windows (the color resets to the system default when switching to the first style). I believe the behavior on Windows is the correct one and is consistent with what XAML developers would normally expect.

After some investigation, I have found another issue that is meant to introduce this behavior on purpose: https://github.com/dotnet/maui/pull/1485. I do not know what is the reasoning behind this change, but introducing such an odd inconsistency between the platforms is a flawed decision in my books. Moreover, without having access to the system palette of the underlying platform, this makes it impossible to express the default platform colors in XAML. The proposed "solution" was to resort to platform-specific code to get the default colors. I do not know what other developers think, but forcing us to use platform-specific code to get the default look of the controls defeats the purpose of a "cross-platform" framework such as .NET MAUI.

### Steps to Reproduce

1. Run the attached sample project
- The main page contains a custom control with a header and a content
2. Click the "Set First Style" button
- The background color of the header changes to gray
- The text color of the header remains the system default color
3. Click the "Set Second Style" button
- The background color of the header changes to dark red
- The text color of the header changes to pink
4. Click the "Set First Style" button again
- The background color of the header changes to gray
- [Android]: The text color of the header remains pink
- [Windows]: The text color of the header resets to the system default

[TestApp.zip](https://github.com/dotnet/maui/files/8504771/TestApp.zip)

### Version with bug

Release Candidate 1 (current)

### Last version that worked well

Preview 14

### Affected platforms

Android

### Affected platform versions

I have not tested on various versions of the different platforms.

### Did you find any workaround?

The only workaround I have found is to always specify a value for the color. This might override the system default value leading to an inconsistent look and feel of the control.

### Relevant log output

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the attached TestApp.zip and reproduce the style-switching sequence on Android, then trace the Android handling of dynamic Style setters and VisualStateManager changes. Done means switching from the second style back to the first restores the unspecified color to the platform default, matching the Windows behavior without requiring a setter for every color.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.