The explanation for this is a bit sad and complex, but fortunately the solution is very easy. You do not need to use AddOwner(...)
.
To block inheritance when using DependencyProperty.OverrideMetadata(...)
, you cannot use the FrameworkPropertyMetadata
constructor to specify the FrameworkPropertyMetadataOptions
flag "OverridesInheritanceBehavior
". The reason is that, for certain FPMO flags, the default FrameworkPropertyMetadata.Merge(...)
function only processes flags that have been explicitly modified via the FPM property setters.
The Inherits
flag/property is another one that also has this behavior, and also you need to clear it from any base metadata. So the only way to have Merge(...)
clear the value that results (after merging with the base property metadata) is to, again, explicitly set it via its FPM setter.
It's confusing and unfortunately a very unnatural/unexpected/non-obvious design, so here is an example. Assume SomeDependencyProperty
is a bool
property, and the base metadata specifies a DefaultValue
of false
, and it has DP inheritance enabled. You want to override the default value to be true
on your derived class MyType
.
So the whole issue discussed on this page/question is that the following doesn't work:
SomeDependencyProperty.OverrideMetadata(typeof(MyType),
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior));
As discussed above, there are two problems with the preceding, but the more obvious one is that, even if the FPMO.OverridesInheritanceBehavior
works as expected, you haven't un-set the FPMO.Inherits
flag itself. Obviously, there's no way to unset a bit flag by ORing
together bit-flags that can only be asserted. So essentially, after the Merge
, you would be overriding the inheritance behavior--but with inheritance still being enabled (due to Merge
). And finally, with inheritance still ultimately enabled, your desired DefaultValue
will essentially have no effect.
Solution
Instead, use the property setters, as shown in the following, which works to block inheritance and, thus, allow your modified DefaultValue
to take effect:
SomeDependencyProperty.OverrideMetadata(typeof(MyType),
new FrameworkPropertyMetadata(true)
{
Inherits = false,
OverridesInheritanceBehavior = true,
});
reference: Merge(...) @ FrameworkPropertyMetadata.cs