如何定义两个在 Xamarin.Forms 中相互更新的可绑定属性?

我想声明一个BindableProperty作为BindablePropertyXamarin.Forms 中另一个的便利属性。设置一个将更新另一个。我不会给出完整的上下文和实际类型,但一个非常简单易懂的场景如下:


我有一个定义 Number 和 Numberp1 属性的视图。Number 是可绑定的,而 Numberp1 属性在这里充当便利属性。


//Definition

public class MyView : ContentView

{

    public static BindableProperty NumberProperty = BindableProperty.Create(nameof(Number), typeof(int), typeof(MyView));


    public int Number { get => (int)GetValue(NumberProperty); set => SetValue(NumberProperty, value); }


    public int Numberp1 { get => Number + 1; set => Number = value - 1; }

}


//Usage

<local:MyView Number="{Binding Number}"/>

事情进展顺利,直到客户发现 Numberp1 不可绑定并且希望我使其可绑定。


<local:MyView Numberp1="{Binding Numberp1}"/>

//error : No property, bindable property, or event found for 'Numberp1', or mismatching type between value and property.

我如何使这两个属性都可绑定但又使它们相互更新?我尝试使用转换器进行调查,但它们似乎只能在绑定中使用,而不是在BindableProperty定义中使用。


智慧大石
浏览 164回答 2
2回答

翻过高山走不出你

事情进展顺利,直到客户发现 Numberp1 不可绑定并且希望我使其可绑定。请为 Numberp1 创建另一个 BindableProperty,BindableProperty“Numberp1Property”的占位符应始终与不带“Property”的名称相匹配。&nbsp; &nbsp;public static BindableProperty NumberProperty = BindableProperty.Create(nameof(Number), typeof(int), typeof(MyView11), null, propertyChanged: OnNumberChanged);&nbsp; &nbsp; private static void OnNumberChanged(BindableObject bindable, object oldValue, object newValue)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var num = (MyView11)bindable;&nbsp; &nbsp; &nbsp; &nbsp; num.Number = (int)newValue;&nbsp; &nbsp; }&nbsp; &nbsp; public static BindableProperty NumberpProperty = BindableProperty.Create(nameof(Numberp), typeof(int), typeof(MyView11), null, propertyChanged: OnNumber1Changed);&nbsp; &nbsp; private static void OnNumber1Changed(BindableObject bindable, object oldValue, object newValue)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var num = (MyView11)bindable;&nbsp; &nbsp; &nbsp; &nbsp; num.Numberp = (int)newValue;&nbsp; &nbsp; }&nbsp; &nbsp; public int Number&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get => (int)GetValue(NumberProperty);&nbsp; &nbsp; &nbsp; &nbsp; set => SetValue(NumberProperty, value);&nbsp; &nbsp; }&nbsp; &nbsp; public int Numberp&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get => Number + 1;&nbsp; &nbsp; &nbsp; &nbsp; set => Number = value - 1;&nbsp; &nbsp; }为 BindableProperty 添加 propertyChanged 事件。

RISEBY

它们都必须定义为 BindableProperty。不幸的是,您不能依赖被调用的 setter 方法,因为运行时不一定通过 setter,它可以直接调用 SetValue,这会更新 BindableProperty 的值的最终来源。但是,您可以相信 BindableProperty 确实会自动为您的任一链接属性获取 PropertyChanged 通知。因此,首先定义两个属性:&nbsp; &nbsp; public static BindableProperty Number1Property = BindableProperty.Create(nameof(Number1), typeof(int), typeof(MyView));&nbsp; &nbsp; public static BindableProperty Number2Property = BindableProperty.Create(nameof(Number2), typeof(int), typeof(MyView));&nbsp; &nbsp; public int Number1 { get => (int)GetValue(Number1Property); set => SetValue(Number1Property, value); }&nbsp; &nbsp; public int Number2 { get => (int)GetValue(Number2Property); set => SetValue(Number2Property, value); }然后,在构造函数中,监听变化:public MyView (){&nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; PropertyChanged += MyView_PropertyChanged;}最后,确保对任何一个的更改传播到另一个,其中 Number2 = Number1 + 1:&nbsp; &nbsp; private void MyView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (e.PropertyName == Number1Property.PropertyName)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Number1 + 1 != Number2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Number2 = Number1 + 1;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (e.PropertyName == Number2Property.PropertyName)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Number1 + 1 != Number2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Number1 = Number2 - 1;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }编辑正如@Knoop 所指出的,OP 希望这些值是相关的,而不是完全相同。
打开App,查看更多内容
随时随地看视频慕课网APP