共用方式為


唯讀相依性屬性

本主題說明唯讀相依性屬性,包括現有的唯讀相依性屬性,以及用於建立自訂唯讀相依性屬性的案例和技術。

必要條件

本主題假設您已了解實作相依性屬性的基本案例,以及如何將中繼資料套用到自訂相依性屬性。 如需相關內容,請參閱自訂相依性屬性相依性屬性中繼資料

現有的唯讀相依性屬性

Windows Presentation Foundation (WPF) 框架中定義的某些相依性屬性是唯讀的。 指定唯讀相依性屬性的一般原因是,這些屬性應該用來判斷狀態,然而該狀態會受到許多因素影響,但從使用者介面設計觀點來看,只將屬性設為該狀態並不恰當。 例如,屬性 IsMouseOver 其實只會呈現從滑鼠輸入所決定的狀態。 藉由規避實際的滑鼠輸入,以程式設計方式設定此值的任何嘗試,都是無法預測且會導致不一致的情況。

由於是不可設定的,因此,唯讀相依性屬性不適合許多相依性屬性通常可提供解決方案 (也就是:資料繫結、可直接設定的樣式值、驗證、動畫、繼承) 的案例。 儘管不可設定,唯讀相依性屬性仍然具有一些屬性系統中相依性屬性所支援的其他功能。 其餘最重要的功能是,唯讀相依性屬性仍可用來做為樣式中的屬性觸發程序。 您無法透過一般通用語言執行平台 (CLR) 屬性啟用觸發程序;它必須是相依性屬性。 先前提及的 IsMouseOver 屬性是下列案例的絕佳範例:此案例相當適合用來定義控制項的樣式,其中一些 visible 屬性 (例如 background、foreground) 或該控制項中複合元素的類似屬性,會在使用者將滑鼠置於控制項的某些定義區域中時變更。 屬性系統固有的失效處理序也可以偵測到並回報唯讀相依性屬性中的變更,這實際上可在內部支援屬性觸發程序功能。

建立自訂唯讀相依性屬性

請務必閱讀前一節,以了解為什麼唯讀相依性屬性不適用許多一般的相依性屬性案例。 但是,如果您有適當的案例,您可能想要建立自己的唯讀相依性屬性。

在建立唯讀相依性屬性的處理序中,許多部分與自訂相依性屬性實作相依性屬性主題中所述的相同。 有三個重大差異:

  • 註冊您的屬性時,請呼叫 RegisterReadOnly 方法而非一般 Register 方法來註冊屬性。

  • 實作 CLR「wrapper」屬性時,請確保 wrapper 也還沒有 set 實作,這樣您所公開的公用 wrapper 唯讀狀態就不會有不一致的情況。

  • 唯讀註冊所傳回的物件是 DependencyPropertyKey 而非 DependencyProperty。 您仍應將此欄位儲存為成員,但通常不需讓它成為類型的公用成員。

不論您必須支援的私用欄位或值為何,當然都能使用您決定的任何邏輯完整寫入您的唯讀相依性屬性。 然而,設定屬性最直接的方法,無論是初始化還是作為執行時邏輯的一部分,都是使用屬性系統的 API,而非繞過屬性系統並直接設定私有支援欄位。 特別是有可接受類型 DependencyPropertyKey 參數的 SetValue 簽章。 在應用程式邏輯中以程式設計方式設定這項值的方式和位置,將影響您第一次註冊相依性屬性時,在建立的 DependencyPropertyKey 上設定存取權的方式。 如果您全都在類別內處理此邏輯,您可能會讓它成為私用,或者如果您需要從組件的其他部分設定它,則可能會將它設為內部。 其中一種方法是在相關事件的類別事件處理程式內呼叫 SetValue,告知類別執行個體需要變更儲存的屬性值。 另一種方法是在註冊過程中,使用配對的 PropertyChangedCallbackCoerceValueCallback 回呼作為這些屬性中繼資料的一部分,將相依性屬性連結在一起。

由於 DependencyPropertyKey 是私有的,不會被屬性系統傳播到程式碼之外,所以唯讀的相依性屬性比可讀寫的相依性屬性安全性更好。 針對讀寫相依性屬性,識別欄位是明確或隱含公開的,因此該屬性是可廣泛設定的。 如需詳細資訊,請參閱相依性屬性的安全性

另請參閱