Share via


可繫結的屬性

.NET 多平臺應用程式 UI (.NET MAUI) 可系結屬性可藉由支援具有 BindableProperty 類型的屬性,而不是字段,來擴充 Common Language Runtime (CLR) 屬性功能。 可系結屬性的目的是提供屬性系統,以支援透過父子式關聯性設定的數據系結、樣式、範本和值。 此外,可系結屬性可以提供預設值、屬性值驗證,以及監視屬性變更的回呼。

在 .NET MAUI 應用程式中,屬性應實作為可系結屬性,以支援下列一或多個功能:

  • 做為數據系結的有效 目標 屬性。 如需目標屬性的詳細資訊,請參閱 基本系結
  • 透過樣式設定 屬性。
  • 提供與屬性類型之預設值不同的預設屬性值。
  • 驗證 屬性的值。
  • 監視屬性變更。

.NET MAUI 可系結屬性的範例包括 Label.TextButton.BorderRadiusStackLayout.Orientation。 每個可系結屬性都有一個在相同類別上公開且為可系結屬性標識符的對應 public static readonlyBindableProperty 別欄位。 例如,屬性的 Label.Text 對應可系結屬性識別碼為 Label.TextProperty

建立可系結屬性

建立可繫結屬性的程式如下:

  1. 使用其中BindableProperty.Create一個方法多載建立BindableProperty實例。
  2. 定義實例的屬性存取子 BindableProperty

所有 BindableProperty 實例都必須在UI線程上建立。 這表示只有在UI線程上執行的程式代碼可以取得或設定可系結屬性的值。 不過, BindableProperty 實例可以透過封送處理至UI線程,從其他線程存取。 如需詳細資訊,請參閱 在UI線程上執行程序代碼。

建立屬性

若要建立 BindableProperty 實例,包含的類別必須衍生自 BindableObject 類別。 不過,類別 BindableObject 階層中類別很高,因此大部分用於UI功能的類別都支援可繫結的屬性。

可以藉由宣告 public static readonly 類型的 BindableProperty屬性來建立可系結屬性。 可系結屬性應該設定為其中一個方法多載的 BindableProperty.Create 傳回值。 宣告應該位於衍生類別的 BindableObject 主體內,但在任何成員定義之外。

建立 時 BindableProperty至少必須指定識別碼,以及下列參數:

  • BindableProperty 的名稱。
  • 屬性的類型。
  • 擁有物件的型別。
  • 屬性的預設值。 這可確保屬性在未設定時一律會傳回特定的預設值,而且與屬性類型的預設值不同。 在可系結屬性上呼叫 方法時 ClearValue ,將會還原預設值。

重要

可系結屬性的命名慣例是可系結的屬性標識碼必須符合 方法中指定的 Create 屬性名稱,並附加 “Property”。

下列程式代碼顯示可系結屬性的範例,其中包含四個必要參數的標識碼和值:

public static readonly BindableProperty IsExpandedProperty =
  BindableProperty.Create ("IsExpanded", typeof(bool), typeof(Expander), false);

這會建立 BindableProperty 名為 IsExpandedProperty的實體,類型為 bool。 屬性是由 Expander 類別所擁有,且預設值為 false

您可以選擇性地在建立 BindableProperty 實體時指定下列參數:

  • 繫結模式。 這會用來指定屬性值變更將傳播的方向。 在預設系結模式中,變更會從 來源 傳播至 目標。 如需詳細資訊,請參閱 基本系結
  • 設定屬性值時要叫用的驗證委派。 如需詳細資訊,請參閱 驗證回呼。
  • 屬性已變更委派,當屬性值變更時,將會叫用。 如需詳細資訊,請參閱 偵測屬性變更
  • 屬性變更委派,將在屬性值變更時叫用。 此委派具有與屬性變更委派相同的簽章。
  • 強制值委派,會在屬性值變更時叫用。 如需詳細資訊,請參閱 Coerce 值回呼。
  • Func,用來初始化預設屬性值。 如需詳細資訊,請參閱 使用 Func 建立預設值。

建立存取子

屬性存取子必須使用屬性語法來存取可系結的屬性。 存取 Get 子應該傳回對應可繫結屬性中包含的值。 呼叫 方法、傳入要取得值的可系結屬性標識符,然後將結果轉換成所需的類型,即可達成 GetValue 此目的。 存取 Set 子應該設定對應可系結屬性的值。 呼叫 方法、傳入要設定值的可系結屬性標識碼,以及要設定的值,即可達成 SetValue 此目的。

下列程式代碼範例顯示可繫結屬性的 IsExpanded 存取子:

public bool IsExpanded
{
    get => (bool)GetValue(IsExpandedProperty);
    set => SetValue(IsExpandedProperty, value);
}

取用可系結屬性

建立可系結屬性之後,就可以從 XAML 或程式代碼取用它。 在 XAML 中,這是藉由宣告具有前置詞的命名空間、指出 CLR 命名空間名稱的命名空間宣告,以及選擇性地宣告元件名稱來達成此目的。 如需詳細資訊,請參閱 XAML 命名空間

下列程式代碼範例示範自定義類型的 XAML 命名空間,其中包含可繫結屬性,其定義於與參考自定義類型的應用程式程式代碼相同的元件內:

<ContentPage ... xmlns:local="clr-namespace:DataBindingDemos" ...>
  ...
</ContentPage>

設定可系結屬性時 IsExpanded 會使用命名空間宣告,如下列 XAML 程式代碼範例所示:

<Expander IsExpanded="true">
    ...
</Expander>

對等的 C# 程式碼會顯示在以下程式碼範例中:

Expander expander = new Expander
{
    IsExpanded = true
};

進階案例

建立 BindableProperty 實例時,有數個可設定為啟用進階可系結屬性案例的選擇性參數。 本節將探討這些案例。

偵測屬性變更

static屬性變更的回呼方法可以藉由指定 propertyChangedBindableProperty.Create 方法的參數,向可系結屬性註冊。 當可系結屬性的值已變更時,將會叫用指定的回呼方法。

下列程式代碼範例示範可系結屬性如何將 IsExpanded 方法註冊 OnIsExpandedChanged 為屬性變更的回呼方法:

public static readonly BindableProperty IsExpandedProperty =
    BindableProperty.Create(nameof(IsExpanded), typeof(bool), typeof(Expander), false, propertyChanged: OnIsExpandedChanged);
...

static void OnIsExpandedChanged (BindableObject bindable, object oldValue, object newValue)
{
  // Property changed implementation goes here
}

在屬性變更回呼方法中 BindableObject ,參數用來表示擁有類別的哪個實例已報告變更,而兩 object 個參數的值代表可系結屬性的舊值和新值。

驗證回呼

static藉由指定 validateValueBindableProperty.Create 方法的參數,即可向可系結屬性註冊驗證回呼方法。 設定可系結屬性的值時,將會叫用指定的回呼方法。

下列程式代碼範例示範可系結屬性如何將 Angle 方法註冊 IsValidValue 為驗證回呼方法:

public static readonly BindableProperty AngleProperty =
    BindableProperty.Create("Angle", typeof(double), typeof(MainPage), 0.0, validateValue: IsValidValue);
...

static bool IsValidValue(BindableObject view, object value)
{
    double result;
    double.TryParse(value.ToString(), out result);
    return (result >= 0 && result <= 360);
}

驗證回呼會提供值,如果值對 屬性有效,則應該傳回 true ,否則 false為 。 如果驗證回呼傳 false回 ,您應該處理例外狀況。 驗證回呼方法的一般用法是在設定可系結屬性時限制整數或雙精度浮點數的值。 例如,方法會 IsValidValue 檢查屬性值是否在 double 0 到 360 的範圍內。

強制值回呼

static藉由指定 coerceValueBindableProperty.Create 方法的參數,即可向可系結屬性註冊強制值回呼方法。 當可系結屬性的值即將變更時,將會叫用指定的回呼方法,以便您可以在套用新值之前調整新值。

重要

除了由可系結的屬性引擎觸發之外,您還可以從程式代碼叫用強制值回呼。 型 BindableObject 別具有方法 CoerceValue ,可藉由叫用其強制強制重新評估其 BindableProperty 自變數的值。

強制重新評估可系結屬性的值即將變更時,會使用Coerce值回呼來強制重新評估可系結屬性。 例如,強制值回呼可用來確保一個可系結屬性的值不大於另一個可系結屬性的值。

下列程式代碼範例示範可系結屬性如何將 Angle 方法註冊 CoerceAngle 為強制值回呼方法:

public static readonly BindableProperty AngleProperty =
    BindableProperty.Create("Angle", typeof(double), typeof(MainPage), 0.0, coerceValue: CoerceAngle);
public static readonly BindableProperty MaximumAngleProperty =
    BindableProperty.Create("MaximumAngle", typeof(double), typeof(MainPage), 360.0, propertyChanged: ForceCoerceValue);
...

static object CoerceAngle(BindableObject bindable, object value)
{
    MainPage page = bindable as MainPage;
    double input = (double)value;

    if (input > page.MaximumAngle)
    {
        input = page.MaximumAngle;
    }

    return input;
}

static void ForceCoerceValue(BindableObject bindable, object oldValue, object newValue)
{
    bindable.CoerceValue(AngleProperty);
}

方法 CoerceAngle 會檢查 屬性的值 MaximumAngle ,如果 Angle 屬性值大於屬性值,則會將值強制轉換成 MaximumAngle 屬性值。 此外,當屬性變更強制值回呼時 MaximumAngle ,會藉由呼叫 方法, Angle 在屬性上叫 CoerceValue 用 。

使用 Func 建立預設值

Func可用來初始化可系結屬性的預設值,如下列範例所示:

public static readonly BindableProperty DateProperty =
    BindableProperty.Create ("Date", typeof(DateTime), typeof(MyPage), default(DateTime), BindingMode.TwoWay, defaultValueCreator: bindable => DateTime.Today);

參數 defaultValueCreator 會設定為 Func ,傳回 DateTime 代表今天日期的 。