一个继承自DependencyObject的类如何使用?

6

我正在跟随这个教程学习依赖对象:http://tech.pro/tutorial/745/wpf-tutorial-introduction-to-dependency-properties

但是,我还是有些困惑。我创建了以下纯粹为了自己学习目的而无实际用途的类:

namespace DPTest
{
    class Audio : DependencyObject
    {
        public static readonly DependencyProperty fileTypeProperty = DependencyProperty.Register("fileType", typeof(String), typeof(Audio),
        new PropertyMetadata("No File Type", fileTypeChangedCallback, fileTypeCoerceCallback), fileTypeValidationCallback);

        public String fileType
        {
            get
            {
                return (String)GetValue(fileTypeProperty);
            }
            set
            {
                SetValue(fileTypeProperty, value);
            }
        }

        private static void fileTypeChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            Console.WriteLine(e.OldValue + " - " + e.NewValue);
        }

        private static object fileTypeCoerceCallback(DependencyObject obj, object o)
        {
            String s = o as String;
            if (s.Length > 0)
            {
                s = s.Substring(0, 8);
            }

            return s;
        }

        private static bool fileTypeValidationCallback(object value)
        {
            return value != null;
        }
    }
}

几个问题:

  1. 为什么属性是静态的?我不完全明白它是否意味着在对象级别存储值。
  2. Coerce回调函数是什么,为什么要包括它?
  3. 我的类的目的是什么,我应该在哪里使用它?
2个回答

8
长话短说,如果您采用Model-View-ViewModel,则很可能不需要使用DependencyObject,但为了回答您的具体问题:
  1. DependencyProperty的定义是静态的,因为所有DependencyObject实例共享该定义。它们就像一个更加高级的每个对象属性字典。这也使得各种框架特性能够无缝地工作,例如绑定或渲染更新

  2. DependencyProperty强制转换发生在需要链接属性更改的情况下。例如,如果您有一个Slider控件,其值应该存在于最小值和最大值之间,您可以使用CoerceValue回调确保它保持在适当的范围内。

  3. DependencyObjects在用户代码中已经不再流行,并被WPF开发中的Model-View-ViewModel模式所取代。您仍然可以在自定义控件开发中找到DependencyObjects。DependencyProperties通常以附加属性的形式出现在用户代码中。


那么在使用WPF进行一般桌面和移动应用程序开发时,使用DependencyProperties实际上没有太多用处?我什么时候可能需要使用它们? - James Jeffery
这是一个非常广泛的问题,我已经在我的第三个答案中进行了概述。 - user7116

3
依赖属性本身是静态的,因为您正在将该属性分配给对象类型。它将属性标识为整体,并且不仅捕获 CLR 属性所捕获的值。
如非静态 CLR 属性中所示,存储功能仅由 SetValue 和 GetValue 处理。您可以将依赖属性值想象成一个大字典,您只需将一些任意内容放入其中即可。字典的键是依赖属性。
强制回调用于将值强制转换为某种格式。在您的情况下,它将确保字符串只有 8 个字符长。大多数时候,您不需要这样的回调。您甚至不经常需要属性更改回调。最常见的情况只是可绑定属性,在那里仅使用标准元数据定义依赖属性就足够了。
您的类的目的是作为示例,我猜测。如果您没有特定的用例,我建议您甚至不要看依赖对象。实际上,您很少对 DependencyObject 进行子类型化。通常,您会拥有继承并添加自定义行为的框架元素或组件。然后,每当您需要 XAML 等的可绑定属性时,就需要依赖属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接