DependencyObject 类

定义

表示参与依赖属性系统的对象。 DependencyObject 是许多重要的 UI 相关类的直接基类,例如 UIElementGeometryFrameworkTemplateStyleResourceDictionary。 有关 DependencyObject 如何支持依赖属性的详细信息,请参阅 依赖属性概述

public ref class DependencyObject
/// [Windows.Foundation.Metadata.ContractVersion(Windows.Foundation.UniversalApiContract, 65536)]
/// [Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
/// [Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
class DependencyObject
[Windows.Foundation.Metadata.ContractVersion(typeof(Windows.Foundation.UniversalApiContract), 65536)]
[Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
[Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
public class DependencyObject
Public Class DependencyObject
继承
Object Platform::Object IInspectable DependencyObject
派生
属性

Windows 要求

设备系列
Windows 10 (在 10.0.10240.0 中引入)
API contract
Windows.Foundation.UniversalApiContract (在 v1.0 中引入)

示例

此示例定义派生自 DependencyObject 的类,并定义附加属性以及标识符字段。 此类的方案是,它是一个服务类,它声明其他 UI 元素可以在 XAML 中设置的附加属性。 服务可能会在运行时对这些 UI 元素的附加属性值执行操作。

public abstract class AquariumServices : DependencyObject
{
    public enum Buoyancy {Floats,Sinks,Drifts}

    public static readonly DependencyProperty BuoyancyProperty = DependencyProperty.RegisterAttached(
      "Buoyancy",
      typeof(Buoyancy),
      typeof(AquariumServices),
      new PropertyMetadata(Buoyancy.Floats)
    );
    public static void SetBuoyancy(DependencyObject element, Buoyancy value)
    {
        element.SetValue(BuoyancyProperty, value);
    }
    public static Buoyancy GetBuoyancy(DependencyObject element)
    {
        return (Buoyancy)element.GetValue(BuoyancyProperty);
    }
}
Public Class AquariumServices
    Inherits DependencyObject
    Public Enum Buoyancy
        Floats
        Sinks
        Drifts
    End Enum

    Public Shared ReadOnly BuoyancyProperty As DependencyProperty = _
          DependencyProperty.RegisterAttached(
          "Buoyancy", _
          GetType(Buoyancy), _
          GetType(AquariumServices), _
          New PropertyMetadata(Buoyancy.Floats))


    Public Sub SetBuoyancy(element As DependencyObject, value As Buoyancy)
        element.SetValue(BuoyancyProperty, value)
    End Sub
    Public Function GetBuoyancy(element As DependencyObject) As Buoyancy
        GetBuoyancy = CType(element.GetValue(BuoyancyProperty), Buoyancy)
    End Function
End Class
public static bool ClearSetProperty(DependencyObject targetObject, DependencyProperty targetDP)
{
    if (targetObject == null || targetDP == null)
    {
        throw new ArgumentNullException();
    }
    object localValue = targetObject.ReadLocalValue(targetDP);
    if (localValue == DependencyProperty.UnsetValue)
    {
        return false;
    }
    else
    {
        targetObject.ClearValue(targetDP);
        return true;
    }
}
Public Shared Function ClearSetProperty(targetObject As DependencyObject, targetDP As DependencyProperty) As Boolean
    If targetObject Is Nothing Or targetDP Is Nothing Then
        Throw New ArgumentNullException()
    End If
    Dim localValue As Object = targetObject.ReadLocalValue(targetDP)
    If localValue = DependencyProperty.UnsetValue Then
        ClearSetProperty = False
    Else
        targetObject.ClearValue(targetDP)
        ClearSetProperty = True
    End If
End Function

此示例演示一个简单的依赖属性声明。 对 GetValue 的调用构成了新依赖属性的属性包装器 的完整 get 访问器实现。 对 SetValue 的调用构成了 set 访问器实现的整个部分。 有关更多示例,请参阅 自定义依赖属性

public class Fish : Control
{
    public static readonly DependencyProperty SpeciesProperty =
    DependencyProperty.Register(
    "Species",
    typeof(String),
    typeof(Fish), null
    );
    public string Species
    {
        get { return (string)GetValue(SpeciesProperty); }
        set { SetValue(SpeciesProperty, (string)value); }
    }
}
Public Class Fish
    Inherits Control

    Public Shared ReadOnly SpeciesProperty As DependencyProperty = _
    DependencyProperty.Register(
    "Species", _
    GetType(String), _
    GetType(Fish), _
    Nothing)
    Public Property Species As String
        Get
            Species = CType(GetValue(SpeciesProperty), String)
        End Get
        Set(value As String)
            SetValue(SpeciesProperty, value)
        End Set
    End Property
End Class

注解

DependencyObject 类在其许多派生类上启用依赖属性系统服务。 有关依赖属性概念的详细信息,请参阅 依赖属性概述

依赖属性系统的主要功能是计算属性值,并提供有关已更改的值的系统通知。 参与依赖属性系统的另一个关键类是 DependencyPropertyDependencyProperty 允许将依赖属性注册到属性系统中,而 DependencyObject 作为基类允许对象使用和设置依赖属性。

以下是 DependencyObject 提供或支持的一些值得注意的服务和特征:

  • 依赖属性托管对现有Windows 运行时依赖属性的支持。
  • 自定义依赖属性承载支持。 可以通过调用 Register 方法并将该方法的返回值存储为 DependencyObject 类中的公共静态属性来注册依赖属性。
  • 附加属性承载对现有Windows 运行时附加属性的支持。
  • 自定义附加属性托管支持。 通过调用 RegisterAttached 方法并将方法的返回值存储为类中的公共静态属性,为附加属性使用注册依赖属性。
  • 获取设置 DependencyObject 上存在的任何依赖属性的值的实用工具方法。 在定义自定义依赖属性“包装器”时,可以使用它们,还可以从应用代码将其用作现有“包装器”属性的替代方法。
  • 用于检查元数据或属性值的高级方案实用工具 (例如 GetAnimationBaseValue) 。
  • 对所有 DependencyObject 实例强制Windows 运行时的main UI 线程的线程关联。
  • 高级线程方案的 Dispatcher 属性。 获取 Dispatcher 值可提供对 CoreDispatcher 对象的引用。 使用 CoreDispatcher,工作线程可以运行使用 DependencyObject 但不在 UI 线程上的代码,因为 CoreDispatcher 可以将执行延迟到不会阻止或以其他方式干扰 UI 线程的异步操作。 请参阅下面的“DependencyObject 和线程处理”部分。
  • 基本数据绑定和样式设置支持,方法是允许将属性设置为表达式,以便在对象的生存期的稍后某个时间计算。 依赖项属性概述中更详细地介绍了这些概念。 另请参阅数据绑定。

DependencyObject 和线程处理

必须在与应用的当前 Window 关联的 UI 线程上创建所有 DependencyObject 实例。 这由系统强制实施,这一点对代码有两个重要影响:

  • 使用来自两个 DependencyObject 实例的 API 的代码将始终在同一线程(始终为 UI 线程)上运行。 在这种情况下,通常不会遇到线程问题。
  • 未在main UI 线程上运行的代码无法直接访问 DependencyObject,因为 DependencyObject 仅具有 UI 线程的线程相关性。 只有 UI 线程上运行的代码才能更改甚至读取依赖属性的值。 例如,使用 .NET 任务 或显式 ThreadPool 线程启动的工作线程将无法读取依赖属性或调用其他 API。

不会完全阻止使用工作线程中的 DependencyObject。 但是,必须从 DependencyObject 获取 一个 CoreDispatcher 对象 (DependencyObject.Dispatcher) 的值,以便跨越应用 UI 线程与系统上运行的任何其他线程之间的有意分离。 CoreDispatcher 公开 RunAsync 方法。 调用 RunAsync 以 (IAsyncAction) 运行可等待的代码。 如果是简单的代码,则可以使用 lambda 表达式,否则可以 (DispatchedHandler) 实现为委托。 系统确定代码可以运行的时间。 由于 DependencyObject.Dispatcher 支持跨线程的访问,因此 DependencyObject.Dispatcher 是 DependencyObject 或其任何子类的唯一实例 API,可以从非 UI 线程访问,而不会引发跨线程异常。 如果尝试从工作线程或任何其他非 UI 线程调用它们,则所有其他 DependencyObject API 都会引发异常。

通常可以在典型的 UI 代码中避免线程问题。 但是,设备通常不与 UI 线程关联。 如果使用从设备获取的信息实时更新 UI,则通常必须获取 CoreDispatcher 才能更新 UI。 另一种情况是,用于访问服务的代码可能不会在 UI 线程上运行。

一种代码方案:如果定义自己的 DependencyObject 类型并尝试将其用于数据源,或者其他方案,DependencyObject 不一定适合 (因为对象与 UI) 不直接相关,因此可能会遇到与 DependencyObject 相关的线程问题。 例如,你可能正在尝试使用后台线程或其他工作线程进行性能优化,这些线程在演示之前或者为了响应设备、服务或其他外部输入而更改对象的值。 评估方案是否真的需要依赖属性;也许标准属性就足够了。

DependencyObject 派生类

DependencyObject 是几个直接派生的类的父类,这些类都是用于应用及其 XAML UI 的编程模型的基础。 下面是一些值得注意的派生类:

构造函数

DependencyObject()

DependencyObject 派生类提供基类初始化行为。

属性

Dispatcher

获取与此对象关联的 CoreDispatcherCoreDispatcher 表示可以访问 UI 线程上的 DependencyObject 的工具,即使代码是由非 UI 线程启动的。

方法

ClearValue(DependencyProperty)

清除依赖属性的本地值。

GetAnimationBaseValue(DependencyProperty)

返回为依赖属性建立的任何基值,该基值适用于动画未处于活动状态的情况。

GetValue(DependencyProperty)

DependencyObject 返回依赖属性的当前有效值。

ReadLocalValue(DependencyProperty)

如果设置了本地值,则返回依赖属性的本地值。

RegisterPropertyChangedCallback(DependencyProperty, DependencyPropertyChangedCallback)

注册通知函数,用于侦听此 DependencyObject 实例上对特定 DependencyProperty 的更改。

SetValue(DependencyProperty, Object)

设置 DependencyObject 上依赖属性的本地值。

UnregisterPropertyChangedCallback(DependencyProperty, Int64)

取消以前通过调用 RegisterPropertyChangedCallback 注册的更改通知。

适用于

另请参阅