您的位置:首页 > 房产 > 建筑 > 网站开发工具软件_小程序定制和第三方开发有什么区别_seo外包网络公司_上线了建站

网站开发工具软件_小程序定制和第三方开发有什么区别_seo外包网络公司_上线了建站

2025/4/24 2:31:02 来源:https://blog.csdn.net/Marzlam/article/details/147241210  浏览:    关键词:网站开发工具软件_小程序定制和第三方开发有什么区别_seo外包网络公司_上线了建站
网站开发工具软件_小程序定制和第三方开发有什么区别_seo外包网络公司_上线了建站

依赖属性与附加属性

  • 依赖属性
    • 对比C#属性
    • WPF依赖属性(Dependency Properties)
    • 优先级计算与值决策​​
    • 回调与验证机制​​
    • WPF 自带的依赖属性
    • 自定义依赖属性
  • 附加属性
    • 本质与定义​​
    • 与依赖属性的区别​​
    • 附加属性的典型应用场景
    • 自定义附加属性
    • 注意事项
  • 属性对比
  • 小结

依赖属性

对比C#属性

首先传统CLR的属性是什么,它们由自动生成的 getter 和 setter 方法管理。例如:

public class Person
{public string Name { get; set; }
}

优点:简单、直接,适用于不需要高级功能的场景。
缺点:它的值是存储在对象的字段中,无法进行数据绑定、样式、动画等功能

WPF依赖属性(Dependency Properties)

那么在WPF中 属性的绑定赋值有很多复杂使用 比如数据绑定 样式绑定等高级功能,所以要有适配WPF技术中的 高级属性使用 也就是 依赖属性

  1. 定义与核心机制​​
    依赖属性是 WPF 中基于 DependencyObject 类实现的一种特殊属性系统。它通过全局哈希表管理属性值,支持动态来源(如绑定、动画、样式等),并允许属性值继承和优先级控制。例如,Button 的 Background 属性可通过多种方式赋值(如直接设置、绑定数据或应用样式)
  2. 核心特点​​
    ​​内存优化高效存储​​:依赖属性通过哈希表存储值,相同控件的相同属性仅保存一份默认值,减少内存消耗。
    ​​动态绑定支持​​:支持与数据源绑定,实现 UI 与业务逻辑的实时同步。
    ​​值继承与优先级​​:子控件可继承父控件的属性值(如 FontSize),且不同来源的值按优先级生效(如本地设置 > 样式 > 继承值)。
    ​​变更通知​​:通过 PropertyChangedCallback 回调响应属性值变化,常用于触发界面更新

优先级计算与值决策​​

既然依赖属性 应对高级使用 多种动态绑定支持 显示值在控件上最终呈现一个值 那肯定有优先级
优先级从高到低依次为:

  1. 动画值​​(如正在执行的动画效果)。
  2. ​​本地值​​(通过 SetValue 或XAML直接设置的值)。
  3. ​​绑定值​​(数据绑定的结果)。
  4. ​​样式与模板​​(通过 Style 或 ControlTemplate 设置的值)。
  5. ​​继承值​​(从父元素继承的值,如 FontSize)。
  6. ​​默认值​​(通过 PropertyMetadata 定义的默认值)

回调与验证机制​​

依赖属性支持通过回调函数实现动态控制和验证:

  1. ​​属性变更回调(PropertyChangedCallback)​​:在值变化时触发,用于更新UI或执行逻辑(如重绘控件)。
  2. ​​强制值回调(CoerceValueCallback)​​:强制调整值(例如限制数值范围),优先级高于动画
  3. ​​验证回调(ValidateValueCallback)​​:验证值的合法性,若无效则抛出异常

WPF 自带的依赖属性

WPF 中绝大多数控件的属性都是依赖属性,它们通过 DependencyProperty 实现,支持动态绑定、动画、样式等特性。以下是常见的​​内置依赖属性​​分类及示例:

  1. 布局与外观​​
    Width/Height:控件的尺寸(如 Button 的宽高)
    Background/Foreground:背景色和前景色(如 TextBox 的背景色)
    FontSize/FontFamily:字体样式(支持继承父容器的字体设置)
  2. ​​行为与交互​​
    IsEnabled:控件是否可用(如禁用按钮)
    Visibility:控件的可见性(支持 Collapsed、Hidden 等状态)
    Command:绑定命令(如 Button 的点击事件绑定 MVVM 命令)
  3. ​​数据绑定与模板​​
    ItemsSource:列表控件的数据源(如 ListBox 的绑定集合)
    Content:内容属性(如 Label 的显示文本)
    ​​特点​​:这些属性通过全局哈希表存储,仅保存非默认值,减少内存占用

自定义依赖属性

这个会结合 自定义控件文章 来讲解
这里就先给个 示例
主要步骤就是 定义控件 注册依赖属性DependencyProperty 包装clr 定义样式 和 布局使用

public class NumericBox : Control
{// 注册依赖属性(含验证)public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(NumericBox),new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,null, CoerceValue),ValidateValue);// CLR 包装器public double Value{get => (double)GetValue(ValueProperty);set => SetValue(ValueProperty, value);}// 强制值回调(限制范围)private static object CoerceValue(DependencyObject d, object value){return Math.Max(0, (double)value); // 确保值 ≥ 0}// 验证回调(拒绝非法值)private static bool ValidateValue(object value){return value is double && (double)value <= 100; // 最大值 100}
}<!-- Window.Resources中自定义样式 --><Style TargetType="{x:Type local:NumericBox}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:NumericBox}"><!-- 模板内容(如文本框、增减按钮等) --><TextBlock Text="{Binding Path=Value, RelativeSource={RelativeSource AncestorType={x:Type local:NumericBox}}}"/></ControlTemplate></Setter.Value></Setter></Style><!-- 使用的布局地方local 使用 -->
<local:NumericBox Width="120" Margin="5,0" Value="{Binding dataItem.Id} />

附加属性

本质与定义​​

  1. 附加属性(Attached Properties)是一种特殊类型的依赖属性,允许将属性“附加”到其他非宿主类的对象上。例如,Grid.Row 属性由 Grid 类定义,但可附加到任何子控件上,用于指定其在网格中的行位置。
  2. ​​实现方式​​:通过 DependencyProperty.RegisterAttached 静态方法注册,并定义 Get 和 Set 静态方法作为访问器。
  3. ​​核心特点​​:
    ​​跨控件扩展​​:无需修改目标控件源码即可添加新属性(如为 TextBox 添加水印提示)。
    ​​全局性​​:可在任何继承自 DependencyObject 的对象上使用。
    ​​

与依赖属性的区别​​

​​宿主差异​​:依赖属性定义在宿主类内部(如自定义控件的属性),而附加属性定义在外部类并附加到其他控件。
​​注册方法​​:依赖属性使用 Register,附加属性使用 RegisterAttached。
​​访问方式​​:附加属性通过静态 Get/Set 方法访问,依赖属性通过 CLR 包装器直接访问

附加属性的典型应用场景

  1. ​​布局控制​​
    ​​网格布局​​:Grid.Row 和 Grid.Column 属性由 Grid 类定义,附加到子元素以指定位置。
    ​​画布定位​​:Canvas.Left 和 Canvas.Top 控制子元素在画布中的坐标。
  2. ​​行为扩展​​
    ​​验证逻辑​​:为 TextBox 添加输入验证或水印提示。
    ​​动态样式​​:通过附加属性触发控件样式的动态变化(如高亮选中项)。
  3. ​​服务类场景​​
    ​​跨组件通信​​:定义服务类,通过附加属性传递全局状态(如用户权限或主题颜色)

自定义附加属性

也会结合自定义控件文章来讲解
这里就先给个 示例
主要步骤就是 定义控件 注册依赖属性DependencyProperty 包装clr 定义样式 和 布局使用

public static class GridHelper
{public static readonly DependencyProperty ShowBorderProperty = DependencyProperty.RegisterAttached("ShowBorder", typeof(bool), typeof(GridHelper), new PropertyMetadata(false, OnShowBorderChanged));public static bool GetShowBorder(DependencyObject obj) => (bool)obj.GetValue(ShowBorderProperty);public static void SetShowBorder(DependencyObject obj, bool value) => obj.SetValue(ShowBorderProperty, value);private static void OnShowBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){if (d is Grid grid && (bool)e.NewValue){// 动态为每个子元素添加边框foreach (var child in grid.Children.OfType<FrameworkElement>()){var border = new Border { BorderBrush = Brushes.Gray, BorderThickness = new Thickness(1) };Grid.SetRow(border, Grid.GetRow(child));Grid.SetColumn(border, Grid.GetColumn(child));grid.Children.Add(border);}}}
}<Grid local:GridHelper.ShowBorder="True"><Grid.RowDefinitions>...</Grid.RowDefinitions><Grid.ColumnDefinitions>...</Grid.ColumnDefinitions><Button Grid.Row="0" Grid.Column="0" Content="按钮" />
</Grid>

注意事项

  1. ​​命名规范​​
    附加属性名称以 Property 结尾(如 ShowBorderProperty)。
    Get/Set 方法需与属性名严格对应(如 GetShowBorder)。
  2. ​​性能优化​​
    避免在回调函数中频繁操作 UI 元素,优先使用数据绑定。
    合理设置默认值以减少初始化开销。
  3. ​​调试技巧​​
    ​​命名空间检查​​:确保 XAML 中正确引入附加属性所在的命名空间。
    ​​模板绑定​​:在自定义控件模板中使用 TemplateBinding 关联附加属性

属性对比

在这里插入图片描述

小结

  1. WPF依赖属性的访问机制通过全局存储、优先级计算和动态回调实现了高效灵活的特性。其核心优势在于支持数据绑定动画样式继承等复杂场景,同时通过优化存储和计算逻辑保证了性能
  2. 附加属性是 WPF 实现灵活 UI 扩展的核心机制,其核心价值在于​​解耦功能与控件​​,支持跨组件通信、动态布局等复杂场景。通过合理设计,开发者可以显著提升代码复用性和可维护性

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com