Xamarin.Forms 可系結的屬性
可系結屬性會藉由使用 類型來備份屬性,而不是使用 欄位來備份屬性 BindableProperty
,藉此擴充 CLR 屬性功能。 可系結屬性的目的是提供屬性系統,以支援透過父子式關聯性設定的數據系結、樣式、範本和值。 此外,可系結屬性可以提供預設值、屬性值驗證,以及監視屬性變更的回呼。
屬性應實作為可系結屬性,以支援下列一或多個功能:
- 做為數據系結的有效 目標 屬性。
- 透過 樣式設定 屬性。
- 提供與屬性類型之預設值不同的預設屬性值。
- 驗證 屬性的值。
- 監視屬性變更。
可繫結屬性的 Xamarin.Forms 範例包括 Label.Text
、 Button.BorderRadius
和 StackLayout.Orientation
。 每個可系結屬性都有一個在相同類別上公開且為可系結屬性標識符的對應 public static readonly
型 BindableProperty
別欄位。 例如,屬性的 Label.Text
對應可系結屬性識別碼為 Label.TextProperty
。
建立可系結屬性
建立可繫結屬性的程式如下:
- 使用其中
BindableProperty.Create
一個方法多載建立BindableProperty
實例。 - 定義實例的屬性存取子
BindableProperty
。
所有 BindableProperty
實例都必須在UI線程上建立。 這表示只有在UI線程上執行的程式代碼可以取得或設定可系結屬性的值。 不過, BindableProperty
您可以使用 方法封送處理至UI線程 Device.BeginInvokeOnMainThread
,以從其他線程存取實例。
建立屬性
若要建立 BindableProperty
實例,包含的類別必須衍生自 BindableObject
類別。 不過,類別 BindableObject
在類別階層中很高,因此大部分用於使用者介面功能的類別都支援可繫結的屬性。
可以藉由宣告 public static readonly
類型的 BindableProperty
屬性來建立可系結屬性。 可系結屬性應該設定為其中一個方法多載的 BindableProperty.Create
傳回值。 宣告應該位於衍生類別的 BindableObject
主體內,但在任何成員定義之外。
建立 時 BindableProperty
至少必須指定識別碼,以及下列參數:
BindableProperty
的名稱。- 屬性的類型。
- 擁有物件的型別。
- 屬性的預設值。 這可確保屬性在未設定時一律會傳回特定的預設值,而且與屬性類型的預設值不同。 在可系結屬性上呼叫 方法時
ClearValue
,將會還原預設值。
重要
可系結屬性的命名慣例是可系結的屬性標識碼必須符合 方法中指定的 Create
屬性名稱,並附加 “Property”。
下列程式代碼顯示可系結屬性的範例,其中包含四個必要參數的標識碼和值:
public static readonly BindableProperty EventNameProperty =
BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null);
這會建立 BindableProperty
名為 EventNameProperty
的實體,類型為 string
。 屬性是由 EventToCommandBehavior
類別所擁有,且預設值為 null
。
您可以選擇性地在建立 BindableProperty
實體時指定下列參數:
- 繫結模式。 這會用來指定屬性值變更將傳播的方向。 在預設系結模式中,變更會從 來源 傳播至 目標。
- 設定屬性值時要叫用的驗證委派。 如需詳細資訊,請參閱 驗證回呼。
- 屬性已變更委派,當屬性值變更時,將會叫用。 如需詳細資訊,請參閱 偵測屬性變更。
- 屬性變更委派,將在屬性值變更時叫用。 此委派具有與屬性變更委派相同的簽章。
- 強制值委派,會在屬性值變更時叫用。 如需詳細資訊,請參閱 Coerce 值回呼。
Func
,用來初始化預設屬性值。 如需詳細資訊,請參閱 使用 Func 建立預設值。
建立存取子
屬性存取子必須使用屬性語法來存取可系結的屬性。 存取 Get
子應該傳回對應可繫結屬性中包含的值。 呼叫 方法、傳入要取得值的可系結屬性標識符,然後將結果轉換成所需的類型,即可達成 GetValue
此目的。 存取 Set
子應該設定對應可系結屬性的值。 呼叫 方法、傳入要設定值的可系結屬性標識碼,以及要設定的值,即可達成 SetValue
此目的。
下列程式代碼範例顯示可繫結屬性的 EventName
存取子:
public string EventName
{
get { return (string)GetValue (EventNameProperty); }
set { SetValue (EventNameProperty, value); }
}
取用可系結屬性
建立可系結屬性之後,就可以從 XAML 或程式代碼取用它。 在 XAML 中,這是藉由宣告具有前置詞的命名空間、指出 CLR 命名空間名稱的命名空間宣告,以及選擇性地宣告元件名稱來達成此目的。 如需詳細資訊,請參閱 XAML 命名空間。
下列程式代碼範例示範自定義類型的 XAML 命名空間,其中包含可繫結屬性,其定義於與參考自定義類型的應用程式程式代碼相同的元件內:
<ContentPage ... xmlns:local="clr-namespace:EventToCommandBehavior" ...>
...
</ContentPage>
設定可系結屬性時 EventName
會使用命名空間宣告,如下列 XAML 程式代碼範例所示:
<ListView ...>
<ListView.Behaviors>
<local:EventToCommandBehavior EventName="ItemSelected" ... />
</ListView.Behaviors>
</ListView>
對等的 C# 程式碼會顯示在以下程式碼範例中:
var listView = new ListView ();
listView.Behaviors.Add (new EventToCommandBehavior
{
EventName = "ItemSelected",
...
});
進階案例
建立 BindableProperty
實例時,有數個可設定為啟用進階可系結屬性案例的選擇性參數。 本節將探討這些案例。
偵測屬性變更
static
屬性變更的回呼方法可以藉由指定 propertyChanged
BindableProperty.Create
方法的參數,向可系結屬性註冊。 當可系結屬性的值變更時,將會叫用指定的回呼方法。
下列程式代碼範例示範可系結屬性如何將 EventName
方法註冊 OnEventNameChanged
為屬性變更的回呼方法:
public static readonly BindableProperty EventNameProperty =
BindableProperty.Create (
"EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
...
static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
}
在屬性變更回呼方法中 BindableObject
,參數用來表示擁有類別的哪個實例已報告變更,而兩 object
個參數的值代表可系結屬性的舊值和新值。
驗證回呼
static
藉由指定 validateValue
BindableProperty.Create
方法的參數,即可向可系結屬性註冊驗證回呼方法。 設定可系結屬性的值時,將會叫用指定的回呼方法。
下列程式代碼範例示範可系結屬性如何將 Angle
方法註冊 IsValidValue
為驗證回呼方法:
public static readonly BindableProperty AngleProperty =
BindableProperty.Create ("Angle", typeof(double), typeof(HomePage), 0.0, validateValue: IsValidValue);
...
static bool IsValidValue (BindableObject view, object value)
{
double result;
bool isDouble = double.TryParse (value.ToString (), out result);
return (result >= 0 && result <= 360);
}
驗證回呼會提供值,如果值對 屬性有效,則應該傳回 true
,否則 false
為 。 如果驗證回呼傳 false
回 ,開發人員應該處理例外狀況。 驗證回呼方法的一般用法是在設定可系結屬性時限制整數或雙精度浮點數的值。 例如,方法會 IsValidValue
檢查屬性值是否在 double
0 到 360 的範圍內。
強制值回呼
static
藉由指定 coerceValue
BindableProperty.Create
方法的參數,即可向可系結屬性註冊強制值回呼方法。 當可系結屬性的值變更時,將會叫用指定的回呼方法。
重要
型 BindableObject
別具有方法 CoerceValue
,可藉由叫用其強制強制重新評估其 BindableProperty
自變數的值。
Coerce 值回呼可用來強制在屬性值變更時重新評估可繫結的屬性。 例如,強制值回呼可用來確保一個可系結屬性的值不大於另一個可系結屬性的值。
下列程式代碼範例示範可系結屬性如何將 Angle
方法註冊 CoerceAngle
為強制值回呼方法:
public static readonly BindableProperty AngleProperty = BindableProperty.Create (
"Angle", typeof(double), typeof(HomePage), 0.0, coerceValue: CoerceAngle);
public static readonly BindableProperty MaximumAngleProperty = BindableProperty.Create (
"MaximumAngle", typeof(double), typeof(HomePage), 360.0, propertyChanged: ForceCoerceValue);
...
static object CoerceAngle (BindableObject bindable, object value)
{
var homePage = bindable as HomePage;
double input = (double)value;
if (input > homePage.MaximumAngle)
{
input = homePage.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 SizeProperty =
BindableProperty.Create ("Size", typeof(double), typeof(HomePage), 0.0,
defaultValueCreator: bindable => Device.GetNamedSize (NamedSize.Large, (Label)bindable));
參數 defaultValueCreator
會設定為 Func
會叫用 方法的 Device.GetNamedSize
,以傳回 double
,代表原生平臺上所使用的 Label
字型具名大小。