问题
There's an exceptional case in WPF where I need to set a dependency property via XAML that actually doesn't get stored itself, but rather is used to set other dependency properties. This is pretty easy since I just use the CoerceValue to intercept the change, do what I want with the passed-in value, then cancel the change on that property. This means when I get that property, I'll still get the default value since I blocked the actual change. Works great.
As an example, when I set this faux CanvasRect="10,10,40,20" DP, internally it actually sets the Canvas.Left, Canvas.Top, Width and Height DPs and CanvasRect itself still remains at its default of "0,0,0,0".
However, I had an idea that if I were to instead read the property, I'd want to re-hydrate that value based on those other dependency properties. This can be done with a simple one-line function...
return new rect(Canvas.GetLeft(this), Canvas.GetTop(this), Width, Height);
Think of it as sort of a CoerceValue but on the getter side, not the setter. However, I'm not sure how, or even if you can use functions to coerce the read-back values like that.
Note: Yes, I know this method would invalidate any change notifications for the CanvasRect DP but I don't care, nor do I actually want that. If I did, I'd instead store an actual rect, then keep it in sync by subscribing to the property changed events of the Canvas.Left, Canvas.Top, Width and Height DPs, which functionally would give me what I want, but this is more of a convenience thing than an actual DP. Plus this is a very simple example to show what I'm asking. The real-world example may be time-based for instance where no DP change notifications would matter anyway.
Now I know I could also simply implement what I wanted in the getter for the .NET wrapper property, but when reading via bindings and such, the .NET property wrapper gets bypassed which is why MSDN says to never use it for anything except for convenient delegation tp the DP. Plus, realistically, for anything other than OneTime, this wouldn't make sense anyway as again, no change notifications would occur.
Anyway, as I said, the DP setter works great, but if I did want to put in the getter, I'm not sure I can think of any other way except to wire up all those change notifications for the related DPs.
Another example of why you may want to do this is because you want to use a value converter for the return value within the property getter itself, perhaps to keep the return values within a certain range, but not lose the actual stored values for other internal purposes.
But back to the basic question here: is there any way to use a function as the default value of a DP, or at least a CoerceValue on the getter side?
回答1:
Value coercion only applies to changing the effective value of a DP. It does not apply to reading a DP's value. You could possibly create another DP that is assigned the value of CanvasRect, such as CachedCanvasRect, and update the cached DP when CanvasRect changes value.
来源:https://stackoverflow.com/questions/5680101/in-wpf-for-a-dp-is-there-any-way-to-use-a-function-to-return-the-default-value