Skip to content
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

Cannot set direct property 'IsPaneOpen' in 'SplitView' because the style has an activator. #9800

Closed
wieslawsoltes opened this issue Dec 28, 2022 · 6 comments · Fixed by #10138
Labels
by-design The behavior reported in the issue is actually correct.

Comments

@wieslawsoltes
Copy link
Collaborator

Describe the bug

Unhandled exception. System.InvalidOperationException: Cannot set direct property 'IsPaneOpen' in 'SplitView.adaptive' because the style has an activator.

Unhandled exception. System.InvalidOperationException: Cannot set direct property 'IsPaneOpen' in 'SplitView.adaptive' because the style has an activator.
   at Avalonia.Styling.Setter.Avalonia.Styling.ISetter.Instance(IStyleInstance instance, StyledElement target) in /_/src/Avalonia.Base/Styling/Setter.cs:line 74
   at Avalonia.Styling.StyleBase.Attach(StyledElement target, IStyleActivator activator, FrameType type) in /_/src/Avalonia.Base/Styling/StyleBase.cs:line 116
   at Avalonia.Styling.Style.TryAttach(StyledElement target, Object host, FrameType type) in /_/src/Avalonia.Base/Styling/Style.cs:line 77
   at Avalonia.StyledElement.ApplyStyle(IStyle style, IStyleHost host, FrameType type) in /_/src/Avalonia.Base/StyledElement.cs:line 790
   at Avalonia.StyledElement.ApplyStyles(IStyleHost host) in /_/src/Avalonia.Base/StyledElement.cs:line 783
   at Avalonia.StyledElement.ApplyStyles(IStyleHost host) in /_/src/Avalonia.Base/StyledElement.cs:line 778
   at Avalonia.StyledElement.ApplyStyling() in /_/src/Avalonia.Base/StyledElement.cs:line 380
   at Avalonia.StyledElement.OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) in /_/src/Avalonia.Base/StyledElement.cs:line 814
   at Avalonia.StyledElement.OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) in /_/src/Avalonia.Base/StyledElement.cs:line 828
   at Avalonia.StyledElement.OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) in /_/src/Avalonia.Base/StyledElement.cs:line 828
   at Avalonia.StyledElement.OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) in /_/src/Avalonia.Base/StyledElement.cs:line 828
   at Avalonia.StyledElement.OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e) in /_/src/Avalonia.Base/StyledElement.cs:line 828
   at Avalonia.StyledElement.Avalonia.Controls.ISetLogicalParent.SetParent(ILogical parent) in /_/src/Avalonia.Base/StyledElement.cs:line 475
   at Avalonia.StyledElement.SetLogicalParent(IList children) in /_/src/Avalonia.Base/StyledElement.cs:line 881
   at Avalonia.StyledElement.LogicalChildrenCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) in /_/src/Avalonia.Base/StyledElement.cs:line 526
   at Avalonia.Visual.LogicalChildrenCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) in /_/src/Avalonia.Base/Visual.cs:line 392
   at Avalonia.Collections.AvaloniaList`1.NotifyAdd(T item, Int32 index) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 700
   at Avalonia.Collections.AvaloniaList`1.Add(T item) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 205
   at Avalonia.Controls.ContentControl.ContentChanged(AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Controls/ContentControl.cs:line 128
   at Avalonia.Controls.ContentControl.<>c.<.cctor>b__4_0(ContentControl x, AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Controls/ContentControl.cs:line 45
   at Avalonia.AvaloniaObjectExtensions.<>c__DisplayClass16_0`1.<AddClassHandler>b__0(AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Base/AvaloniaObjectExtensions.cs:line 414
   at System.Reactive.AnonymousObserver`1.OnNextCore(T value) in /_/Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs:line 67
   at System.Reactive.ObserverBase`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/ObserverBase.cs:line 34
   at System.Reactive.Subjects.Subject`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 145
   at Avalonia.AvaloniaProperty`1.NotifyChanged(AvaloniaPropertyChangedEventArgs`1 e) in /_/src/Avalonia.Base/AvaloniaProperty`1.cs:line 65
   at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaProperty`1 property, Optional`1 oldValue, BindingValue`1 newValue, BindingPriority priority, Boolean isEffectiveValue) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 662
   at Avalonia.PropertyStore.EffectiveValue`1.SetAndRaiseCore(ValueStore owner, StyledPropertyBase`1 property, T value, BindingPriority priority) in /_/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs:line 194
   at Avalonia.PropertyStore.EffectiveValue`1.SetLocalValueAndRaise(ValueStore owner, StyledPropertyBase`1 property, T value) in /_/src/Avalonia.Base/PropertyStore/EffectiveValue`1.cs:line 68
   at Avalonia.PropertyStore.ValueStore.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority) in /_/src/Avalonia.Base/PropertyStore/ValueStore.cs:line 205
   at Avalonia.AvaloniaObject.SetValue[T](StyledPropertyBase`1 property, T value, BindingPriority priority) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 329
   at Avalonia.Controls.ContentControl.set_Content(Object value) in /_/src/Avalonia.Controls/ContentControl.cs:line 56
   at BehaviorsTestApplication.Views.MainWindow.!XamlIlPopulate(IServiceProvider, MainWindow) in /Users/wieslawsoltes/Documents/GitHub/AvaloniaBehaviors/samples/BehaviorsTestApplication/Views/MainWindow.axaml:line 6
   at BehaviorsTestApplication.Views.MainWindow.!XamlIlPopulateTrampoline(MainWindow)
   at BehaviorsTestApplication.Views.MainWindow.InitializeComponent() in /Users/wieslawsoltes/Documents/GitHub/AvaloniaBehaviors/samples/BehaviorsTestApplication/Views/MainWindow.axaml.cs:line 19
   at BehaviorsTestApplication.Views.MainWindow..ctor() in /Users/wieslawsoltes/Documents/GitHub/AvaloniaBehaviors/samples/BehaviorsTestApplication/Views/MainWindow.axaml.cs:line 12
   at BehaviorsTestApplication.App.OnFrameworkInitializationCompleted() in /Users/wieslawsoltes/Documents/GitHub/AvaloniaBehaviors/samples/BehaviorsTestApplication/App.axaml.cs:line 19
   at Avalonia.Controls.AppBuilderBase`1.Setup() in /_/src/Avalonia.Controls/AppBuilderBase.cs:line 289
   at Avalonia.Controls.AppBuilderBase`1.SetupWithLifetime(IApplicationLifetime lifetime) in /_/src/Avalonia.Controls/AppBuilderBase.cs:line 148
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 208
   at BehaviorsTestApplication.Program.Main(String[] args) in /Users/wieslawsoltes/Documents/GitHub/AvaloniaBehaviors/samples/BehaviorsTestApplication/Program.cs:line 14

To Reproduce
Steps to reproduce the behavior:

    <Style Selector="SplitView.adaptive">
      <Setter Property="IsPaneOpen" Value="False" />
    </Style>

Expected behavior

No exceptions.

Screenshots

Desktop (please complete the following information):

  • OS: MacOS
  • Version master, 11.0.999-cibuild0026718-beta

Additional context
Add any other context about the problem here.

@maxkatz6 maxkatz6 added by-design The behavior reported in the issue is actually correct. and removed bug labels Dec 28, 2022
@maxkatz6
Copy link
Member

By design. It's not possible to set a dynamic value to the direct property via styles. It is possible to remove 'adaptive' class from the SplitView, but it's not possible to remove direct property value. In 0.10 it was undefined behavior.

Also, with 11.0 it's possible to create a ControlTheme, and set setter to the direct property without any activators/style-classes.

@maxkatz6
Copy link
Member

Potentially we want to have a compile-time error for this scenario as well.

@robloo
Copy link
Contributor

robloo commented Dec 29, 2022

@maxkatz6

Why is this a direct property? Can all you maintainers please have a deep discussion about this and document the outcome? I think several direct properties should not actually be direct. This should be resolved in 11.0 API.

Instead, direct properties should be reserved only for "data" as you put it which includes content, read-only collections and that's about it (I'm sure there are a few exceptions though).

#9719 (reply in thread)

Also, with 11.0 it's possible to create a ControlTheme, and set setter to the direct property without any activators/style-classes.

That's good at least

@TomEdwardsEnscape
Copy link
Contributor

Today I updated to a nightly build of Avalonia and hit this problem multiple times in our application. In our case, we are setting Button.Command to different values in various triggers activatable styles. In the latest preview this is fine, but in the nightly build it causes a crash.

I'm with @robloo here. If you are going to crash the application (or emit a compile error) when setting certain property types from certain styles, then the use of those property types needs to be VERY carefully considered.

I would go even further than robloo's suggestion: in light of these changes, DirectProperty should be restricted to read-only properties. This is the only safe way to proceed. Even "data" values can reasonably set in a style, if you have multiple distinct values that you want to switch between depending on UI state.

Of course there are ways to work around these issues, such as creating a proxy StyledProperty which sets the target DirectProperty when its own value changes. We can move ahead in our application port with these in place. But these are clearly hacks that Avalonia should be changed to get rid of.

@grokys I believe this change was related to the ValueStore refactor?

@maxkatz6
Copy link
Member

maxkatz6 commented Jan 9, 2023

@tomenscape fyi DirectProperties styling never worked properly. It always was an undefined behavior, as you can apply style with these setters, but you cannot remove it.
If you were using styles to reuse Command [not a styled] property between multiple buttons with a class name, you should consider using ControlTheme instead in 11.0.

I absolutely agree that we shouldn't release 11.0 with runtime crash for the direct properties, but I believe we should add compile time error with helping information.

@TomEdwardsEnscape
Copy link
Contributor

We are using ControlTheme everywhere, and those themes often contains activatable styles. Our use case is actually low-level controls (e.g. Button) which appear within the templates of high-level controls, and the selectors are something like ^[Foo=bar] /template/ #SomeButton.

I understand the problems that come with setting direct properties from this context, but since we never wanted to remove these values, only to switch between multiple different options, that has never been a problem for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
by-design The behavior reported in the issue is actually correct.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants