使用 DependencyProperty 时,如何区分继承值和分配值

When using a DependencyProperty, how can I tell the the difference between an inherited value and an assigned one

DependencyProperty 系统在很多方面都非常有用,但目前给我带来一点麻烦的是 DataContext 属性 进行一些类型检查。请参阅下面我当前的方法,它已经阻止无效类型导致奇怪 magic-sting-namespace-collisions,但实际上不会在分配值时出错。

唯一的问题是我不知道如何区分一个值以 属性 结尾的两种方式。谁能告诉我怎么做?

当前方法:

(请原谅错误,这是凭记忆输入的,所以可能有一些错误,但它给出了想法。)

基础Class

public class MyControlBase : FrameworkElement
{

    static MyControlBase() 
    {
        DataContextProperty.OverrideDefaultMetadata(
            new FrameworkPropertyMetadata(
                DataContextProperty.GetMetadata(typeof(MyControlBase)).DefaultValue,
                (s,e) => {},
                (s,e) =>
                {
                    var sender = s as MyControlBase;
                    if (sender == null || e == null || sender.ExpectedType == null) 
                        return e;
                    var oOut = sender.ExpectedType == typeof(e) ? e : null;
                    // WANTED:
                    if (!IsInheritedDPValue(sender, DataContextProperty) && e != null && oOut == null)
                        throw ArgumentException("Assigned value not of expected type");
                    return Out;
                }
            )
        );
    }

    public static readonly DependencyProperty ExpectedTypeProperty = 
        DependencyProperty.Register(
            "ExpectedType", 
            typeof(Type),
            typeof(MyControlBase)
            new PropertyMetadata(null)
        );
    public Type ExpectedType {
        get {return GetValue(ExpectedTypeProperty) as Type;}
        set {SetValue(ExpectedTypeProperty, value);}
    }

}

Child 类

public class MyControlT1 {
    static MyControlT1()
    {
        ExpectedTypeProperty.OverrideDefaultMetadata(
            new FrameworkPropertyMetadata(
                typeof(MyControlT1ViewModel)
            )
        );
    }
}

如果您想知道值是如何分配给依赖项 属性,您可以使用

DependencyPropertyHelper.GetValueSource(DependencyObject dependencyObject, DependencyProperty dependencyProperty)

这个方法returns一个ValueSource对象,它有一个BaseValueSource属性。它是一个枚举,根据值的来源(继承、本地值、触发器等)具有值。

如果该值是从父对象继承的,则 BaseValueSource 的值将是 Inherited。如果该值直接分配给元素,则该值将为 Local

您可以在此处查找 BaseValueSource 的所有可能值:https://msdn.microsoft.com/en-us/library/system.windows.basevaluesource%28v=vs.110%29.aspx