改进的 IValueConverter —— MarkupExtension 还是 DependencyObject?
我在网上看到了两种不同的方法来增强 IValueConverter。其中一个从 MarkupExtension 扩展了 ValueConverter,另一个从 DependencyObject 扩展。我无法同时扩展两者,所以我想知道是否其中一个比另一个更好?
I saw online 2 different approaches to enhancing an IValueConverter. One of them extended a ValueConverter from MarkupExtension, the other from DependencyObject. I can't extend from both, so I'm wondering if any one is better than the other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从每个派生都可以为您提供不同类型的功能和灵活性:
从
MarkupExtension
派生使您能够使用值转换器,而无需将其设为静态资源,如下所述:在XAML中,无需创建StaticResource就可以直接使用:
此类代码在调试时非常方便,因为您只需编写
local:DebugMe
即可调试使用它的控件的 DataContext。从
DependencyObject
派生,您可以以更具表现力的方式使用某些首选项配置值转换器,如下所述:在XAML中,您可以直接将其用作:
它有什么作用?如果字符串
FullDescription
超过50
个字符,它会截断它!@crazyarabian 评论说:
确实如此。但那是不可绑定的;也就是说,当您从
MarkupExtension
派生时,则不能执行以下操作:但是如果您从
DependencyObject
派生转换器,则可以执行上述操作。从这个意义上说,与MarkupExtension
相比,它更具表现力。请注意,目标属性必须是
DependencyProperty
才能使Binding
发挥作用。 MSDN 说,Deriving from each gives you different kind of power and flexibility:
Deriving from
MarkupExtension
enables you to use the value converter without making it a static resource, as described below:In XAML, you can directly use it without creating a StaticResource:
Such code is very handy when debugging, as you can just write
local:DebugMe
and then can debug the DataContext of the control on which you use it.Deriving from
DependencyObject
enables you to configure the value converter with some preferences in a more expressive way, as described below:In XAML, you can directly use it as:
What does it do? It truncates the string
FullDescription
if it is more than50
characters!@crazyarabian commented that:
That is true. But then that is not bindable; that is, when you derive from
MarkupExtension
, then you cannot do :But if you derive your converter from
DependencyObject
, then you can do the above. In that sense, it is more expressive compared toMarkupExtension
.Note that the target property must be a
DependencyProperty
forBinding
to work. MSDN says,由于它是我的库,您引用它作为扩展
DependencyObject
的转换器的示例,我我觉得自己解释一下比较合适。实际上,我首先简单地以
Object
作为基类实现IValueConverter
。我转而扩展 DependencyObject 的唯一原因是允许采用由 Josh Smith 首创的称为虚拟分支的技术。您可以在此处了解该技术。假设您想做这样的事情:
这将不起作用,因为资源不是可视化树的一部分,因此绑定将失败。虚拟分支解决了这个小难题,使您能够执行这样的绑定。但是,与任何其他 WPF 绑定一样,它仍然依赖于
DependencyObject
目标。因此,如果我只是实现了IValueConverter
而不扩展DependencyObject
,那么您将无法使用虚拟分支。现在,如果我完全诚实的话,我不确定如果有机会的话我还会这样做。我自己实际上从未不得不使用虚拟分支 - 我只是想启用该场景。我什至可能会在我的库的未来版本中更改这一点。因此,我的建议是坚持使用
Object
的基类(或其简单派生类),除非您确实认为需要虚拟分支。Since it's my library you're citing as an example of converters that extend
DependencyObject
, I think it fitting to explain myself.I actually started out by simply implementing
IValueConverter
withObject
as my base class. The only reason I switched to extendingDependencyObject
was to allow for a technique - pioneered by Josh Smith - called virtual branching. You can read about that technique here.Suppose you want to do something like this:
This won't work because resources are not part of the visual tree, and so the binding will fail. Virtual branching hacks around this little dilemma, enabling you to perform such a binding. However, it still relies - like any other WPF binding - on the target being a
DependencyObject
. Thus, if I simply implementedIValueConverter
without extendingDependencyObject
, you would be precluded from using virtual branches.Now, if I'm completely honest, I'm not sure I'd still do this if I had my time again. I've never actually had to use a virtual branch myself - I just wanted to enable the scenario. I may even change this in a future version of my library. So my advice would be stick to a base class of
Object
(or a simple derivative thereof) unless you really think you'll need virtual branching.