uno icon indicating copy to clipboard operation
uno copied to clipboard

`VisualState` `Setter` value precedence is too high

Open MartinZikmund opened this issue 4 years ago • 5 comments

Current behavior

Currently when a VisualState in a VisualStateGroup is applied, its Setters are applied with Animations precedence. This seems different from UWP, where the set value can be then overwritten by manually setting the property in code.

Expected behavior

Local should be used.

How to reproduce it (as minimally and precisely as possible)

Workaround

Environment

Nuget Package:

  • [x] Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia
  • [ ] Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia
  • [ ] Uno.SourceGenerationTasks
  • [ ] Uno.UI.RemoteControl / Uno.WinUI.RemoteControl
  • [ ] Other:

Nuget Package Version(s):

Affected platform(s):

  • [x] iOS
  • [x] Android
  • [x] WebAssembly
  • [x] WebAssembly renderers for Xamarin.Forms
  • [x] macOS
  • [x] Skia
    • [x] WPF
    • [x] GTK (Linux)
    • [x] Tizen
  • [x] Windows
  • [ ] Build tasks
  • [ ] Solution Templates

IDE:

  • [ ] Visual Studio 2017 (version: )
  • [x] Visual Studio 2019 (version: )
  • [ ] Visual Studio for Mac (version: )
  • [ ] Rider Windows (version: )
  • [ ] Rider macOS (version: )
  • [ ] Visual Studio Code (version: )

MartinZikmund avatar Feb 05 '21 21:02 MartinZikmund

This is unlikely to be a case of swapping one 'wrong' precedence for the 'right' one unfortunately. Uno's and UWP's precedence handling are just different. Uno's DependencyProperty system is heavily based off of WPF's; UWP's DP system is a streamlined and simplified version of the WPF system, which gives the same result most of the time, but differs in edge cases like this one and https://github.com/unoplatform/uno/issues/3443.

davidjohnoliver avatar Feb 07 '21 10:02 davidjohnoliver

@davidjohnoliver It seems it will be a bit more tricky, as the original value returns once the custom state is unapplied. So it does behave partially as a "stack", but not completely, as changing the local value overwrites the setter.

MartinZikmund avatar Feb 07 '21 14:02 MartinZikmund

I agree with @davidjohnoliver we have to review our precedence system. This is also linked to https://github.com/unoplatform/uno/issues/631 and https://github.com/unoplatform/uno/issues/3739

dr1rrb avatar Feb 08 '21 20:02 dr1rrb

Closed #5171 as the solution I attempted there was not adequate.

MartinZikmund avatar Oct 31 '22 08:10 MartinZikmund

My findings from WinUI source code:

We should have a flag IsLocalValueNewerThanAnimationsValue

The flag by default is false. Then:

  1. When we set or clear a value for Animations, set the flag to false.
  2. When we set a value for Local, set the flag to true.
  3. When we set a value for non-Local non-Animations, set it to false (it doesn't make much sense to me, but that's what I'm seeing in WinUI code)
  4. When getting a DP value, if the highest precedence is Animations and IsLocalValueNewerThanAnimationsValue is true, we return the Local value.

For 3, this is the part of the code I'm referring to:

image

There should still be a missing part here, because if we clear Local value, we should set the flag to false. Not sure where this happens in WinUI code.

Youssef1313 avatar Feb 16 '24 10:02 Youssef1313