public abstract class ConverterMarkupExtension : MarkupExtension
{
private static readonly Dictionary<Type, IValueConverter> Converters = new();
protected ConverterMarkupExtension()
{
if (!typeof(IValueConverter).IsAssignableFrom(GetType()))
throw new Exception($"{nameof(ConverterMarkupExtension)} can only be used with {nameof(IValueConverter)}");
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if(!Converters.ContainsKey(GetType()))
Converters.Add(GetType(), (IValueConverter)Activator.CreateInstance(GetType())!);
return Converters[GetType()];
}
}
4条答案
按热度按时间mwyxok5s1#
好吧,我只是根本不在xaml中声明它们。相反,我还从
MarkupExtension
派生了一个转换器。像这样:这允许我在任何地方使用转换器,如下所示:
其中converters是我声明转换器的命名空间。
从一个旧的stackoverflow线程中学习到这个技巧。
j9per5c42#
我有一个ResourceDictionary,它声明了几个常用的转换器,比如bool-to-visibility转换器。我在App. xaml中直接引用了这个字典。
我在Page/Window级别(或在Page/Window引用的ResourceDictionary中)声明了其他更特定于给定情况的转换器。
我不能明确地回答性能问题,但如果它在加载时间或内存使用方面有实际的不同,我会非常惊讶。声明一个转换器基本上就是一个对象示例化,所以它应该非常高效,并且使用很少的内存,但是我还没有做任何分析来比较应用程序级与窗口级性能。
c2e8gylq3#
如果你只需要一个窗口的转换器,我会把它放在一个窗口(甚至只是容器控件,持有使用它的控件)。
我认为这更易于维护-您可以查看转换器声明,并能够告诉什么使用它。您知道,如果您将该特定页面上的控件更改为不再使用转换器,则可以将其从页面的资源中取出,而不会影响其他任何内容。相反,如果转换器是一个应用程序资源,那么要确定是什么在使用它(如果有的话)就不那么简单了。
如果同一个转换器被多个页面使用,我将
still
放在每个页面资源下。实际上,它只是XAML中多了一行。无论如何,这是我的观点,从今天开始。我期待着另一个帖子,争论完全相反。:—)
wsxa1bj14#
@Yogesh的回答很棒。为了完整起见,我创建了一个基类,以减少代码: