使用 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
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