Skip to content

DependencyProperty.RegisterDependencyProperty.RegisterAttached 这两个方法都属于 WinUI 3(Windows App SDK)中的 Microsoft.UI.Xaml 命名空间,用于注册依赖属性,但用途和语义有显著区别。

🔍 一、总体对比概览

特性RegisterRegisterAttached
用途注册普通依赖属性(属于自身类)注册附加属性(可被其他类使用)
定义位置在属性所属类中定义拥有该附加属性的类中定义(通常是服务类或布局类)
调用时机类初始化时(静态构造)类初始化或应用启动时
典型场景自定义控件的属性(如 MyControl.Value布局系统(如 Grid.Row)、行为扩展
Getter/Setter 模式普通属性包装(GetValue/SetValue必须提供 GetXXXSetXXX 静态方法
返回值用途存入 public static readonly 字段存入 public static readonly 字段

📚 二、逐项分析两个方法的描述

1. DependencyProperty.Register(普通依赖属性注册)

✅ 方法签名(C#)

csharp
public static DependencyProperty Register(
    string name,
    Type propertyType,
    Type ownerType,
    PropertyMetadata typeMetadata)

✅ 参数说明(来自网页)

  • name: 要注册的依赖属性的名称(如 "Value")。
  • propertyType: 属性的类型(如 typeof(int))。
  • ownerType: 注册该属性的类的类型(如 typeof(MyControl))。
  • typeMetadata: 属性元数据,可包含默认值、属性变更回调等。

✅ 返回值

  • 一个 DependencyProperty 标识符,应赋值给类中的 public static readonly 字段(如 ValueProperty)。

✅ 关键描述(来自网页)

“Registers a dependency property with the specified property name, property type, owner type, and property metadata for the property.”

“Use this method when defining or initializing a DependencyObject derived class that will own the registered dependency property.”

“A dependency property identifier that typically is stored in a public static readonly field in your DependencyObject derived class.”

“How to register a custom dependency property is described in detail (with examples) in the topic Custom dependency properties.”

✅ 示例代码(简化)

csharp
public class MyControl : Control
{
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register(
            "Value",
            typeof(int),
            typeof(MyControl),
            new PropertyMetadata(0)
        );

    public int Value
    {
        get => (int)GetValue(ValueProperty);
        set => SetValue(ValueProperty, value);
    }
}

✅ 重点:这是为 MyControl 自身定义一个叫 Value 的属性。


2. DependencyProperty.RegisterAttached(附加属性注册)

✅ 方法签名(C#)

csharp
public static DependencyProperty RegisterAttached(
    string name,
    Type propertyType,
    Type ownerType,
    PropertyMetadata defaultMetadata)

✅ 参数说明(与 Register 几乎相同)

  • name: 附加属性的名称(如 "Dock")。
  • propertyType: 属性类型。
  • ownerType: 拥有该附加属性的类的类型(如 typeof(DockPanel))。
  • defaultMetadata: 默认元数据。

✅ 返回值

  • 同样是一个 DependencyProperty 标识符,也应存入 public static readonly 字段。

✅ 关键描述(来自网页)

“Registers an attached dependency property with the specified property name, property type, owner type, and property metadata for the property.”

“A dependency property identifier that should be used to set the value of a public static readonly field in your class. That identifier is then used to reference the attached property later, for operations such as setting its value programmatically or attaching a Binding.”

示例代码

csharp
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)
        );

    // 必须提供静态 Get/Set 方法
    public static void SetBuoyancy(DependencyObject element, Buoyancy value)
    {
        element.SetValue(BuoyancyProperty, value);
    }

    public static Buoyancy GetBuoyancy(DependencyObject element)
    {
        return (Buoyancy)element.GetValue(BuoyancyProperty);
    }
}

✅ 重点:AquariumServices 类本身可能不是 UI 元素,但它“提供”了一个可以被其他 UI 元素使用的属性 Buoyancy

🔁 三、核心区别总结

对比维度RegisterRegisterAttached
属性归属属性属于 ownerType 类自身属性由 ownerType 类“提供”,但可被任何 DependencyObject 子类使用
使用方式实例直接访问:control.Value = 100;静态方法访问:DockPanel.SetDock(button, Dock.Left);
XAML 语法<local:MyControl Value="100" /><Button local:DockPanel.Dock="Left" />
设计意图扩展控件自身功能实现“跨类扩展”或“服务注入”机制
Getter/Setter普通实例属性包装必须提供 public static GetXXXSetXXX 方法
典型应用自定义控件属性布局(Grid.Row)、行为(i:InvokeCommandAction)、附加服务

🎯 四、通俗类比

类比RegisterRegisterAttached
现实比喻给手机加一个“音量键”功能给所有电器加一个“智能插座”状态(如“是否通电”)
代码比喻Person 类添加 Age 属性为所有 UIElement “附加”一个 TooltipService.ToolTip 属性
XAML 比喻<Button Content="OK" /><Button ToolTip="点击提交" />

✅ 五、总结:两个方法的本质区别

RegisterRegisterAttached
谁拥有?属性属于类自己类“提供”属性,但别人使用
怎么用?实例属性访问静态方法 + XAML 扩展语法
为什么用?实现控件的可绑定属性实现跨类功能扩展(布局、行为、服务)