Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

DataBinding in XAML ignores access modifiers

Open hematec opened this issue 9 months ago • 2 comments

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.

hematec avatar May 15 '24 09:05 hematec

Is it with or without compiler bindings enabled? You can also check by writing "{ReflectionBinding TestString}" or "{CompiledBinding TestString}".

maxkatz6 avatar May 15 '24 10:05 maxkatz6

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);

hematec avatar May 15 '24 12:05 hematec