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

时间:2019-04-23 11:34:20

标签: c# xamarin.forms

我想声明一个BindableProperty,它充当Xamarin.Forms中另一个BindableProperty的便捷属性。设置一个将更新另一个。我不会提供完整的上下文和实际类型,但是一个非常简单易懂的方案如下:

我有一个定义Number和Numberp1属性的视图。数字是可绑定的,而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.

我如何使这两个属性可绑定但又使它们彼此更新?我尝试使用Converters进行调查,但它们似乎只能在Binding上使用,而不能在BindableProperty定义上使用。

2 个答案:

答案 0 :(得分:1)

它们都必须定义为BindableProperty。不幸的是,您不能依赖于被调用的setter方法,因为运行时不一定要通过setter,它可以直接调用SetValue,后者将更新BindableProperty值的确定来源。

但是,您可以依靠BindableProperty确实为您的两个链接属性自动获取PropertyChanged通知的事实。

因此,首先定义两个属性:

    public static BindableProperty Number1Property = BindableProperty.Create(nameof(Number1), typeof(int), typeof(MyView));
    public static BindableProperty Number2Property = BindableProperty.Create(nameof(Number2), typeof(int), typeof(MyView));
    public int Number1 { get => (int)GetValue(Number1Property); set => SetValue(Number1Property, value); }
    public int Number2 { get => (int)GetValue(Number2Property); set => SetValue(Number2Property, value); }

然后,在构造函数中,侦听更改:

public MyView ()
{
    InitializeComponent();

    PropertyChanged += MyView_PropertyChanged;
}

最后,确保对其中一个的更改传播到另一个,其中Number2 = Number1 + 1:

    private void MyView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == Number1Property.PropertyName)
        {
            if (Number1 + 1 != Number2)
                Number2 = Number1 + 1;
        }
        if (e.PropertyName == Number2Property.PropertyName)
        {
            if (Number1 + 1 != Number2)
                Number1 = Number2 - 1;
        }
    }

编辑如@Knoop所述,OP希望相关的值相互关联,而不是完全相同。

答案 1 :(得分:1)

  

一切顺利,直到客户发现Numberp1不可绑定,并希望我使其可绑定。

请为Numberp1创建另一个BindableProperty,BindableProperty'Numberp1Property'的占位符应始终与不带'Property'的名称匹配。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="false">localhost</domain>
        <domain includeSubdomains="false">10.0.2.2</domain>
        <domain includeSubdomains="false">10.0.3.2</domain>
    </domain-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

为BindableProperty添加propertyChanged事件。