簡體   English   中英

如何定義兩個在 Xamarin.Forms 中相互更新的可綁定屬性?

[英]How do I define two bindable properties which update each other in Xamarin.Forms?

我想聲明一個BindableProperty ,它充當 Xamarin.Forms 中另一個BindableProperty的便利屬性。 設置一個將更新另一個。 我不會給出完整的上下文和實際類型,但一個非常簡單易懂的場景如下:

我有一個定義 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.

我如何使這兩個屬性都可綁定但又使它們相互更新? 我嘗試使用 Converters 進行調查,但它們似乎只能在 Binding 中使用,而不是BindableProperty定義。

事情進展順利,直到客戶發現 Numberp1 不可綁定並且希望我使其可綁定。

請為 Numberp1 創建另一個 BindableProperty,BindableProperty“Numberp1Property”的占位符應始終與不帶“Property”的名稱相匹配。

   public static BindableProperty NumberProperty = BindableProperty.Create(nameof(Number), typeof(int), typeof(MyView11), null, propertyChanged: OnNumberChanged);

    private static void OnNumberChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var num = (MyView11)bindable;
        num.Number = (int)newValue;
    }

    public static BindableProperty NumberpProperty = BindableProperty.Create(nameof(Numberp), typeof(int), typeof(MyView11), null, propertyChanged: OnNumber1Changed);

    private static void OnNumber1Changed(BindableObject bindable, object oldValue, object newValue)
    {
        var num = (MyView11)bindable;
        num.Numberp = (int)newValue;
    }

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

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

為 BindableProperty 添加 propertyChanged 事件。

它們都必須定義為 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 希望這些值是相關的,而不是完全相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM