Avalonia
Avalonia copied to clipboard
DataBinding in XAML ignores access modifiers
Describe the bug
When you have a private property in a viewmodel, this property is accessible for binding in views XAML code. Also the access modifiers for getter or setter are ignored from views XAML code.
To Reproduce
have a viewmodel with: `public class TestViewModel : ReactiveObject, IActivatableViewModel { public ViewModelActivator Activator { get; } = new ViewModelActivator();
string _TestString = "Hello World";
private string TestString
{
get => _TestString;
set => this.RaiseAndSetIfChanged(ref _TestString, value);
}
}`
XAML code of view:
<TextBox Text="{Binding TestString}" />
Initially "Hello World" is shown in textbox and when you change the text, the setter is called.
Expected behavior
Have no access to private/internal properties and/or getters/setters from View's XAML.
Avalonia version
11.1.0-beta2
OS
Windows
Additional context
I did not dive to deep into the source of Avalonia, but i think the properties are bound using reflection and that the bindign flags of the property is ignored.
Is it with or without compiler bindings enabled? You can also check by writing "{ReflectionBinding TestString}" or "{CompiledBinding TestString}".
Hi maxkatz,
In my initial test i used reflection bindings.
I just tested it with compiler bindings and it works like expected.
Bind to private properties throws an exception and even if i have a public property and just make the setter private, the setter won't be called when i change the text in textbox.
So is this a desired behavior for reflection binding?
F.e. i saw in "InpcPropertyAccessorPlugin.cs"
private const BindingFlags PropertyBindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
and f.e. in "private PropertyInfo? GetFirstPropertyWithName(object instance, string propertyName)"
if (instance is IReflectableType reflectableType && instance is not Type) return reflectableType.GetTypeInfo().GetProperty(propertyName, PropertyBindingFlags);