在WPF中,对于DP,有没有办法使用函数返回默认值或在getter端有一个CoerceValue?
WPF 中有一种特殊情况,我需要通过 XAML 设置一个依赖属性,该属性实际上不会存储本身,而是用于设置其他依赖属性。这非常简单,因为我只是使用 CoerceValue 来拦截更改,对传入的值执行我想要的操作,然后取消对该属性的更改。这意味着当我获得该属性时,我仍然会获得默认值,因为我阻止了实际的更改。效果很好。
举个例子,当我设置这个人造 CanvasRect="10,10,40,20" DP 时,它在内部实际上设置了 Canvas.Left、Canvas.Top、宽度和高度 DP,并且 CanvasRect 本身仍然保持默认值“0” ,0,0,0”。
但是,我有一个想法,如果我要读取该属性,我想根据其他依赖属性重新水合该值。这可以通过一个简单的单行函数来完成...
return new rect(Canvas.GetLeft(this), Canvas.GetTop(this), Width, Height);
将其视为一种 CoerceValue,但位于 getter 一侧,而不是 setter 一侧。但是,我不确定如何,或者即使您可以使用函数来强制这样的读回值。
注意:是的,我知道此方法会使任何更改通知无效 对于 CanvasRect DP 但我不 关心,我实际上也不想那样。如果 我这样做了,我会存储一个实际的 正确,然后保持同步 订阅属性已更改 Canvas.Left、Canvas.Top 的事件, 宽度和高度 DP, 功能上会给我什么 想要,但这更多的是 比实际的DP方便。 另外,这是一个非常简单的例子来展示我的要求。 现实世界的例子可能是 基于时间的例如没有 DP 的情况 无论如何,更改通知都很重要。
现在我知道我也可以简单地在 .NET 包装器属性的 getter 中实现我想要的内容,但是当通过绑定等读取时,.NET 属性包装器会被绕过这就是为什么 MSDN 说除了方便向 DP 委派之外不要将其用于任何其他用途。另外,实际上,对于 OneTime 以外的任何内容,这无论如何都没有意义,因为不会发生任何更改通知。
不管怎样,正如我所说,DP setter 工作得很好,但如果我确实想放入 getter,我不确定除了为相关 DP 连接所有这些更改通知之外我还能想到任何其他方法。
为什么您可能想要这样做的另一个例子是因为您想在属性 getter 本身内使用值转换器作为返回值,也许是将返回值保持在一定范围内,但不会丢失其他内部的实际存储值目的。
但回到这里的基本问题:有没有办法使用函数作为 DP 的默认值,或者至少在 getter 端使用 CoerceValue?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
值强制仅适用于更改 DP 的有效值。它不适用于读取 DP 的值。您可以创建另一个分配有 CanvasRect 值的 DP,例如 CachedCanvasRect,并在 CanvasRect 更改值时更新缓存的 DP。
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.