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

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

重要

.NET 7 和 .NET 6 的桌面指南檔正在建置中。

必要條件

本文假設您具備相依性屬性的基本知識,而且您已閱讀 相依性屬性概觀 。 若要遵循本文中的範例,如果您熟悉可延伸的應用程式標記語言(XAML),並知道如何撰寫 WPF 應用程式,它很有説明。

現有的唯讀相依性屬性

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

唯讀相依性屬性的使用

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

注意

只有相依性屬性,而非一般 Common Language Runtime 屬性,可以做為樣式中的屬性觸發程式。

建立自訂唯讀相依性屬性

建立唯讀的相依性屬性之前,請先檢查 不適用的案例

建立唯讀相依性屬性的程式有許多方式,類似于建立讀寫相依性屬性,但有下列差異:

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

設定應用程式內唯讀相依性屬性的值,將如何影響您指派給儲存 的 DependencyPropertyKey 類別成員的存取層級。 如果您只從註冊相依性屬性的類別內設定屬性值,您可以使用 private 存取修飾詞。 針對相依性屬性值彼此影響的情況,您可以使用配對 PropertyChangedCallbackCoerceValueCallback 回呼來觸發值變更。 如需詳細資訊,請參閱 相依性屬性中繼資料

如果您需要從註冊它的類別外部變更唯讀相依性屬性的值,您可以使用 internalDependencyPropertyKey 存取修飾詞。 例如,您可以從相同元件中的事件處理常式呼叫 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 之人的寫入權限時,請使用唯讀相依性屬性。

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

另請參閱