Avalonia
Avalonia copied to clipboard
OneWayToSource bindings don't work for read-only direct properties
@grokys Found a bug: after the refactor, OneWayToSource bindings don't work for read-only direct properties, i.e.:
<Border>
<Border.ContextFlyout>
<Flyout IsOpen="{CompiledBinding IsOpen, Mode=OneWayToSource}">
<Border />
</Flyout>
</Border.ContextFlyout>
</Border>
Unhandled exception. System.ArgumentException: The property IsOpen is readonly.
at Avalonia.DirectProperty`2.InvokeSetter(AvaloniaObject instance, BindingValue`1 value) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/DirectProperty.cs:line 119
at Avalonia.AvaloniaObject.SetDirectValueUnchecked[T](DirectPropertyBase`1 property, BindingValue`1 value) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/AvaloniaObject.cs:line 819
at Avalonia.DirectPropertyBase`1.RouteSetDirectValueUnchecked(AvaloniaObject o, Object value) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/DirectPropertyBase.cs:line 164
at Avalonia.PropertyStore.ValueStore.Avalonia.Data.Core.IBindingExpressionSink.OnChanged(UntypedBindingExpressionBase instance, Boolean hasValueChanged, Boolean hasErrorChanged, Object value, BindingError error) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/PropertyStore/ValueStore.cs:line 765
at Avalonia.Data.Core.UntypedBindingExpressionBase.PublishValue(Object value, BindingError error) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/Data/Core/UntypedBindingExpressionBase.cs:line 429
at Avalonia.Data.Core.BindingExpression.StartCore() in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/Data/Core/BindingExpression.cs:line 379
at Avalonia.Data.Core.UntypedBindingExpressionBase.Start(Boolean produceValue) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/Data/Core/UntypedBindingExpressionBase.cs:line 473
at Avalonia.Data.Core.UntypedBindingExpressionBase.AttachAndStart(IBindingExpressionSink subscriber, AvaloniaObject target, AvaloniaProperty targetProperty, BindingPriority priority) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/Data/Core/UntypedBindingExpressionBase.cs:line 208
at Avalonia.PropertyStore.ValueStore.AddBinding(AvaloniaProperty property, UntypedBindingExpressionBase source) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/PropertyStore/ValueStore.cs:line 55
at Avalonia.AvaloniaObject.Bind(AvaloniaProperty property, IBinding binding, Object anchor) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/AvaloniaObject.cs:line 635
at Avalonia.AvaloniaObject.Bind(AvaloniaProperty property, IBinding binding) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/AvaloniaObject.cs:line 421
at Avalonia.AvaloniaObjectExtensions.Bind(AvaloniaObject target, AvaloniaProperty property, IBinding binding, Object anchor) in /Users/bartek/Programowanie/temp/Avalonia/src/Avalonia.Base/AvaloniaObjectExtensions.cs:line 251
at ControlCatalog.MainWindow.!XamlIlPopulate(IServiceProvider, MainWindow) in /Users/bartek/Programowanie/temp/Avalonia/samples/ControlCatalog/MainWindow.xaml:line 42
at ControlCatalog.MainWindow.!XamlIlPopulateTrampoline(MainWindow)
at ControlCatalog.MainWindow.InitializeComponent() in /Users/bartek/Programowanie/temp/Avalonia/samples/ControlCatalog/MainWindow.xaml.cs:line 32
at ControlCatalog.MainWindow..ctor() in /Users/bartek/Programowanie/temp/Avalonia/samples/ControlCatalog/MainWindow.xaml.cs:line 25
at ControlCatalog.App.SetCatalogThemes(CatalogTheme theme) in /Users/bartek/Programowanie/temp/Avalonia/samples/ControlCatalog/App.xaml.cs:line 99
at ControlCatalog.App.Initialize() in /Users/bartek/Programowanie/temp/Avalonia/samples/ControlCatalog/App.xaml.cs:line 40
Originally posted by @BAndysc in https://github.com/AvaloniaUI/Avalonia/issues/13970#issuecomment-1920429841
I wasn't sure whether I should create an issue for this if the change is not live on the stable version, but actually it makes sense to do it since the PR is already merged 😅 thanks
that is what I think nightly is for.
cc @grokys
This one is relatively big bug, as OneWayToSource is commonly used on read-only properties
I don't see how we can fix this without using some heuristics to find the underlying field of a read-only property. I would instead prefer to keep the behavior as is because I don't think one should mutate a read-only property in XAML.
@hez2010 OneWayToSource means the control reports it's state to the VM but not the other way around. That is a totally valid use case. You can bind to IsEffectivelyEnabled for example or ItemsCount or whatever readonly property.
This should have been fixed by https://github.com/AvaloniaUI/Avalonia/pull/14513 I think?
This should have been fixed by #14513 I think?
Yes and It works perfectly fine, this issue was opened before the fix :)