唯讀相依性屬性

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

必要條件

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

現有的唯讀相依性屬性

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

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

建立自訂唯讀相依性屬性

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

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

  • 註冊屬性時,呼叫 RegisterReadOnly 方法,而不是屬性註冊的一般 Register 方法。

  • 實作 CLR 「wrapper」 屬性時,請確定包裝函式也沒有任何集合實作,因此,您公開的公用包裝函式不會有不一致的狀態。

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

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

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

另請參閱