-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Style Setters Apply Bindings to Themselves Rather than the Element Being Styled #8547
Comments
Just wondering if this is being given any consideration? It's still present in 1.5. Is there a workaround I'm not aware of? I would have thought the inability to pre-set bindings via style setters would impact a lot of control designers. I see the documentation Migration Notes discusses this so I realize it's a known issue, but it seems more like a bug than a missing feature. Either way I don't think it would be a breaking change because there's no conceivable reason you'd want the |
As your link states:
Sounds like it isn't a "missing feature", "known issue", or a bug, you just can't use a Binding there by design. |
Pretty poor design to let you assign a binding as a setter value that then does nothing. I'd like to think the MS team is a bit smarter than to do that "by design". And fortunately WinUI3 doesn't use the Windows Runtime, otherwise I wouldn't be using it. |
Because that was so hard: https://stackoverflow.com/questions/72899903/binding-in-a-style-setter-in-winui-3/78408646#78408646 |
WinUI 3 is built on top of WinRT. https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/?view=windows-app-sdk-1.5 |
No, it's a refactor of WinRT out of the OS and into the application layer. Meaning Microsoft can finally start fixing some of the 10-year-old techncial debt - like what we're talking about - leftover from the "Metro" days without having to update the OS. |
Moving some of the code out of the OS doesn't change the fact that it is still a part of WinRT, it just makes deploying changes easier.
I agree that silent failures are bad. Otherwise, considering this is how it works and it's documented, I'd say this decision was a part of the design process relating to increasing performance by discouraging the use of slow reflection-based binding that your workaround relies on. |
Oh were you part of the design process? Otherwise why are you opining? |
I don't have to opine that it isn't supported for performance reasons. I can just read the Setter.cpp, Style.cpp, and OptimizedStyle.cpp source code. It shows all of the logic regarding how Style Setters are optimized and mutable setters are handled. They strictly rely on subscribing to dependency property notifications and not having special handling for the Binding markup extension (among other things) like WPF. https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Setter.cs https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Style.cs https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/StyleHelper.cs (main binding handling logic) |
No one is talking about mutable setters. I want to assign a BindingBase instance to an immutable Setter Value and have that binding be applied into a BindingExpression and the binding source resolved with respect to the target FE at the time the Style is applied, like every other XAML framework does it, and NOT with respect to the Style/Setter instance itself which is 100% objectively useless. I'm assuming what you're talking about has to do with ThemeResource as a replacement for DynamicResource, but there is no reason Setter.Value can't accept a dumb and unevaluated Binding instance directly assigned to it just like it accepts any other simple value and just not do anything with it until the appropriate time. The fact that I could do what I did in my workaround without sacrificing whatever "performance" optimizations are the supposed reason this critical feature isn't possible proves that it in fact is possible. The only reason I can't make my solution more elegant (e.g. no I indeed shouldn't have to use reflection to get the target DP) is because 90% of everything in this maddeningly inflexible framework is sealed or otherwise not extensible. Anyway I don't see anyone from MS closing the issue as "as designed" so rather than argue with me pointlessly why don't we see what TPTB actually have to say shall we? |
Per the WPF documentation on Binding performance, every 1000 Binding setups takes ~100ms. If Bindings were supported in styles and setup at runtime, then each time new XAML elements were created there could be noticeable delays. The more controls with Style Setters using Bindings, the worse the perf. 50 controls with 5 Binding Setters = ~25ms wait time. https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/optimizing-performance-data-binding
Per the documentation you provided and the source code itself, full Binding support in Style Setters is not supported, only limited, one-time bindings:
// We support only limited, one-time bindings on style setters.
// To get the resolved value, create a temp setter, set the binding on
// its Value property, then get the resolved value from Setter.Value.
// This is equivalent to how the final resolved value is set on a
// non-optimized style setter, where it's set while the setter is
// unparented, and the setter is sealed when added to a collection. The source indicates Setter Bindings are setup and resolved once per style in a limited manner by design. A BindingBase is not stored in Setter.Value for later use like WPF. |
Then don't use style bindings and you won't be impacted by any fix to this bug/design flaw. For everyone else it'll be no worse than declaring the bindings individually for each control like we have to do now. I'll roll the dice that my users aren't on Surface RT tablets anymore.
Which don't actually do anything useful because at the time they're being evaluated there's no data context or other way to intelligently resolve a binding source. Hence, bug/design flaw.
Awesome, thanks for pinpointing the source of the bug/design flaw.
Except it's not equivalent, because at the time it tries to resolve the binding here, it uses the
Exactly. Hence bug/design flaw. I authored the original Relativesource and Multibinding implementations for Xamarin Forms and MAUI, and made other contributions to their XAML compiler, ok? I know how this stuff works and how to do it efficiently and the Microsoft devs are a heck of a lot better at this than me. So please stop clogging this issue with irrelevant arguments over design intent and let Microsoft decide whether they want to address this limitation or not. Thanks. |
Describe the bug
When using a
Binding
forSetter.Value
in aStyle
, I would expect, as in WPF, that theSetter
instance wouldn't actually be the binding target, but, rather, once theStyle
is applied, theBinding
would be applied to each element receiving theStyle
.Instead, it seems the
Setter
instance becomes the binding target literally, which is quite useless. Therefore something like this:doesn't work, because
Self
evaluates to theSetter
, rather than the element theStyle
is being applied to.Steps to reproduce the bug
Here is a trivial example that, while rather silly, does exemplify the problem:
Expected behavior
The button background should be green by virtue of setting the
BorderBrush
property.Instead this error is logged in the console:
Error: BindingExpression path error: 'BorderBrush' property not found on 'Microsoft.UI.Xaml.Setter'. BindingExpression: Path='BorderBrush' DataItem='Microsoft.UI.Xaml.Setter'; target element is 'Microsoft.UI.Xaml.Setter' (Name='null'); target property is 'Value' (type 'Object')
In other words, as noted, the binding is being applied immediately with the style setter as the target, rather than the recipient of the style.
Screenshots
No response
NuGet package version
WinUI 3 - Windows App SDK 1.3.1: 1.3.230502000
Windows version
Windows 11 (22H2): Build 22621, Windows 11 (21H2): Build 22000
Additional context
No response
The text was updated successfully, but these errors were encountered: