Xamarin.Forms在(在 iOS 模拟器上测试)中考虑以下稍微复杂的情况:
- 一个
GenericPage超类继承自ContentPage并包含一个BindableProperty - 一个
Page继承自GenericPagewith a 的类ViewModel,它绑定到BindablePropertyusing aOneWayToSource绑定模式 - 一个
GenericControl超类继承自ContentView并包含一个BindableProperty - 一个
Control继承自GenericControlwith a 的类ControlViewModel,它绑定到BindablePropertyusing aOneWayToSource绑定模式 - 类
Control被嵌入到Page类中XAML,并且使用绑定模式从类BindableProperty中GenericControl绑定到属性ViewModelOneWay
我可以验证从Page到BindablePropertyof的“连接”GenericControl确实有效,因为该propertyChanged方法是使用 inGenericControl中的默认值调用BindableProperty的GenericPage。我还可以验证 to 的“连接”GenericControl是否正在使用 in中的默认值调用ControlViewModel属性设置器in 。ControlViewModelBindablePropertyGenericControl
但是,由于某种原因,到达BindablePropertyin的更改GenericControl(来自GenericPage或外部设置的默认值)不会传播到ControlViewModel.
完整代码位于:https ://github.com/mlxyz/Xamarin-Forms-Binding-Repro
通用页面:
public static readonly BindableProperty TestProperty =
BindableProperty.Create(nameof(Test), typeof(Vector3), typeof(GenericPage), new Vector3(1, 2, 3));
public Vector3 Test
{
get => (Vector3)GetValue(TestProperty);
set => SetValue(TestProperty, value);
}
页:
<views:GenericPage Test="{Binding Test, Mode=OneWayToSource}" x:Name="Root">
<views:GenericPage.BindingContext>
<viewModels:ViewModel />
</views:GenericPage.BindingContext>
<ContentPage.Content>
<controls:Control Test="{Binding Source={x:Reference Root}, Path=BindingContext.Test, Mode=OneWay}" />
</ContentPage.Content>
</views:GenericPage>
视图模型:
public Vector3 Test
{
get => _test;
set
{
_test = value;
OnPropertyChanged();
}
}
通用控制:
// bindable property and associated property is defined basically the same as in GenericPage except for propertyChanged property set and different default values
private static void PropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
{
System.Diagnostics.Debug.WriteLine("property changed"); // <- this is called with default values from GenericPage (1,2,3)
}
控制:
<controls:GenericControl Test="{Binding Test, Mode=OneWayToSource}">
<controls:GenericControl.BindingContext>
<viewModels:ControlViewModel />
</controls:GenericControl.BindingContext>
</controls:GenericControl>
控制视图模型:
public Vector3 Test
{
get => _test;
set => _test = value; // <- this gets called only with default values from `GenericControl` (4,5,6)
}
