如何在XAML中注入一个转换器

8
我有一个IValueConverter实现类,我需要使用我的DI容器(Ninject)进行注入。
问题是,在XAML中,没有明显的方法来控制转换器对象的实例化。
因此,我的XAML包含了这样一行代码:

Source="{Binding Path=CurrentMessage, Converter={StaticResource ImagePathConverter}}"

其中,ImagePathConverter会为我创建。
我想我可以创建一个"服务定位器"静态类并调用它来解析我的依赖项并将StaticResource更改为属性"MyServiceLocator.TheImageConverter",但这让我想呕吐。
我希望这个问题能够通过几个特定于提供的代码段的代码片段和支持示例的链接来回答。而不仅仅是建议去看某个地方。
另外,请非常重视,假设XAML没有代码后台,我不能使用代码后台。我正在创建一个 皮肤,不想要一个代码后台。因此,我无法在类构造函数中设置类变量并引用它。也许这是不合理的,我还不确定。

我很想知道为什么你需要使用 DI 来解决转换器的问题..? - NotDan
因为转换器使用(依赖)格式化类,该类具有自己的依赖项,每个依赖项也可能有依赖项。这就是 DI 的全部意义 - 为我连接所有这些依赖项。我想知道是否有很多人只是用它来创建新对象,而没有意识到主要目的? - PandaWood
如果我理解正确的话,您实际上并不想将Converter本身注入到另一个类中,而是想将依赖项注入到转换器中,对吗? - Oliver Giesen
2个回答

9

处理这个问题的常见方法是让您的转换器也成为一个MarkupExtension。即:

public class MyConverter : MarkupExtension, IValueConverter

您的ProvideValue()方法可以返回您的转换器的实例,从而使您可以像这样使用它:

Source="{Binding CurrentMessage, Converter={local:MyConverter SomeParameterToConverter}}"

这与依赖注入并没有太大关系,但它确实满足了你消除代码后台的需求。我并不认为将转换器注册到依赖注入容器中有什么意义。


1
谢谢,你对转换器的担忧是合理的。 如果你没有看到将转换器注册到 DI 容器中的优点,我认为你假设 DI 容器只是用来“new up”对象。关键在于,所讨论的 Converter 类还有其他依赖项,这些依赖项只能通过 DI 容器解决(例如以单例范围注册的“配置”对象)。 - PandaWood
我认为这是一个很好的答案,当我能够解决“映射指令中缺少XmlNamespace、Assembly或ClrNamespace”错误时,我会回来看它(即使已经添加了xmlns:local="clr-namespace:MyNamespace")。 - PandaWood
1
明白了!已经修复了错误,现在运行得很好。我仍然需要在ProvideValue方法中以服务定位器的方式调用我的DI,但我认为这是无法避免的。 - PandaWood

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接