共用方式為


唯讀相依性屬性 (WPF .NET)

您可以使用唯讀相依性屬性來防止其他使用者從程式碼外部設定屬性值。 本文將探討現有的唯讀相依性屬性,以及用於建立自訂唯讀相依性屬性的案例和技術。

必要條件

本文假設您具備相依性屬性的基本知識,而且已閱讀相依性屬性概觀。 若要遵循本文中的範例,建議您先熟悉 Extensible Application Markup Language (XAML),並了解如何撰寫 WPF 應用程式。

現有的唯讀相依性屬性

唯讀相依性屬性通常是報告狀態,而且不應透過 public 存取子修改。 例如,Windows Presentation Foundation (WPF) 架構會將 IsMouseOver 屬性實作為唯讀,因為其值應只可由滑鼠輸入來決定。 如果 IsMouseOver 允許其他輸入,其值可能會與滑鼠輸入不一致。 許多現有的唯讀相依性屬性雖然無法透過 public 存取子進行設定,但都有多個輸入所決定的值。

使用唯讀相依性屬性

若是相依性屬性通常會提供解決方案的案例,則不適用唯讀相依性屬性。 不適用的案例包括資料繫結、將樣式套用至值、驗證、動畫和繼承。 不過,唯讀相依性屬性可用為樣式中的屬性觸發程式。 例如,IsMouseOver 通常用來在滑鼠停留時觸發控制項的背景、前景或其他可見屬性之變更。 WPF 屬性系統會偵測並報告唯讀相依性屬性中的變更,因此支援屬性觸發程式功能。 實作集合類型相依性屬性時,唯讀相依性屬性也十分實用,其中只有集合元素需要寫入,而不是集合物件本身。 如需詳細資訊,請參閱集合類型相依性屬性 (部分機器翻譯)。

注意

只有相依性屬性可以做為樣式中的屬性觸發程式,而非一般通用語言執行平台屬性。

建立自訂唯讀相依性屬性

建立唯讀的相依性屬性之前,請先查看不適用的案例 (部分機器翻譯)。

建立唯讀相依性屬性程式的流程與建立讀寫相依性屬性十分類似,但有下列差異:

您可以使用您選擇的任何邏輯來判斷唯讀相依性屬性的值。 設定屬性值的建議方式 (無論是一開始或做為執行階段邏輯的一部分),是使用接受類型為 DependencyPropertyKey 之參數的 SetValue 多載。 建議使用 SetValue 來規避屬性系統,並直接設定備份欄位。

設定應用程式內唯讀相依性屬性值的的方式和位置,將影響您指派給儲存 DependencyPropertyKey 之類別成員的存取層級。 如果您只從註冊相依性屬性的類別內設定屬性值,您可以使用 private 存取修飾元。 若發生相依性屬性值彼此影響的情況,您可以使用成對的 PropertyChangedCallbackCoerceValueCallback 回呼來觸發值變更。 如需詳細資訊,請參閱相依性屬性中繼資料 (部分機器翻譯)。

如果您需要從註冊的類別外部來變更唯讀相依性屬性的值,您可以使用 DependencyPropertyKeyinternal 存取修飾元。 例如,您可以從相同組件中的事件處理程式呼叫 SetValue。 下列範例會定義 Aquarium 類別,該類別會呼叫 RegisterReadOnly 以建立唯讀的相依性屬性 FishCountDependencyPropertyKey 會指派至 internal static readonly 欄位,讓相同組件中的程式碼可以變更唯讀的相依性屬性值。

public class Aquarium : DependencyObject
{
    // Register a dependency property with the specified property name,
    // property type, owner type, and property metadata.
    // Assign DependencyPropertyKey to a nonpublic field.
    internal static readonly DependencyPropertyKey FishCountPropertyKey =
        DependencyProperty.RegisterReadOnly(
          name: "FishCount",
          propertyType: typeof(int),
          ownerType: typeof(Aquarium),
          typeMetadata: new FrameworkPropertyMetadata());

    // Declare a public get accessor.
    public int FishCount =>
        (int)GetValue(FishCountPropertyKey.DependencyProperty);
}
Public Class Aquarium
    Inherits DependencyObject

    ' Register a dependency property with the specified property name,
    ' property type, owner type, And property metadata.
    ' Assign DependencyPropertyKey to a nonpublic field.
    Friend Shared ReadOnly FishCountPropertyKey As DependencyPropertyKey =
        DependencyProperty.RegisterReadOnly(
            name:="FishCount",
            propertyType:=GetType(Integer),
            ownerType:=GetType(Aquarium),
            typeMetadata:=New FrameworkPropertyMetadata())

    ' Declare a public get accessor.
    Public ReadOnly Property FishCount As Integer
        Get
            Return GetValue(FishCountPropertyKey.DependencyProperty)
        End Get
    End Property

End Class

因為 WPF 屬性系統不會在程式碼外部散佈 DependencyPropertyKey,因此唯讀相依性屬性的寫入安全性比讀寫相依性屬性更好。 當您想要限制具有 DependencyPropertyKey 參考之使用者的寫入存取權時,請使用唯讀相依性屬性。

相反地,不論您指派的存取修飾元為何,都可以透過屬性系統,來存取讀寫相依性屬性的相依性屬性識別碼。 如需詳細資訊,請參閱相依性屬性的安全性

另請參閱