【发布时间】:2020-07-15 11:06:46
【问题描述】:
考虑Xamarin.Forms 中的以下有点复杂的情况(在 iOS 模拟器上测试):
- 一个
GenericPage超类继承自ContentPage并包含一个BindableProperty - 一个
Page类从GenericPage继承,其中ViewModel使用OneWayToSource绑定模式绑定到BindableProperty - 一个
GenericControl超类继承自ContentView并包含一个BindableProperty - 一个
Control类继承自GenericControl,其中ControlViewModel使用OneWayToSource绑定模式绑定到BindableProperty -
Control类使用XAML嵌入到Page类中,GenericControl的BindableProperty使用ViewModel绑定模式绑定到来自ViewModel类的属性
我可以验证从Page 到GenericControl 的BindableProperty 的“连接”确实有效,因为propertyChanged 方法在GenericControl 中调用,默认值来自@ 中的BindableProperty 987654356@。我还可以验证从GenericControl 到ControlViewModel 的“连接”是否作为ControlViewModel 中的属性设置器使用GenericControl 中BindableProperty 中的默认值调用。
但是,由于某种原因,到达BindableProperty 中的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)
}
【问题讨论】:
-
您的代码不完整,所以找不到原因。最好提供完整的代码或示例,以便我可以直接在我身边进行测试。另外,这里有一个类似的问题,也许可以帮助你stackoverflow.com/questions/62894322/…
-
感谢您对此进行调查。我在这里推送了代码:github.com/mlxyz/Xamarin-Forms-Binding-Repro
标签: c# xaml xamarin xamarin.forms xamarin.ios