【问题标题】:Should I declare converters in App.xaml or as a per-file resource?我应该在 App.xaml 中声明转换器还是作为每个文件的资源?
【发布时间】:2009-11-02 03:17:54
【问题描述】:

在 WPF 应用程序中声明转换器时,我应该:

  1. 在 App.xaml(即<Application.Resources/>)中声明所有我的转换器,以便整个应用程序都可以使用它
  2. Resources 部分中为每个Page/Window/ResourceDictionary/UserControl 等声明只需要的转换器
  3. 完全不同的东西

关于可读性,方法 1 对我来说似乎是最好的,但我的问题是关于性能。就性能、内存等而言,哪种方法的资源效率最高?

【问题讨论】:

    标签: wpf performance ivalueconverter


    【解决方案1】:

    好吧,我根本不在 xaml 中声明它们。相反,我还从MarkupExtension 派生了一个我的转换器。像这样:

    public class MyValueConverter : MarkupExtension, IValueConverter
    {
        private static MyValueConverter _converter = null;
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null) _converter = new MyValueConverter();    
            return _converter;
        }
    
        public object Convert
         (object value, Type targetType, object parameter, CultureInfo culture) { }
        public object ConvertBack
         (object value, Type targetType, object parameter, CultureInfo culture) { }
    }
    

    这让我可以在任何地方使用我的转换器,如下所示:

    Source="{Binding myValue, Converter={converters:MyValueConverter}}"
    

    converters 是我声明转换器的命名空间。

    仅从旧的 stackoverflow 线程中学到了这个技巧。

    【讨论】:

    • 是的,这在性能方面更好,因为它不会在每次使用转换器时都实例化一个新对象。它只在第一次调用 MarkupExtension 返回之前创建一个实例,并且每次都返回相同的实例。
    • 谢谢!这让生活更轻松。
    • 为什么要为 MarkupExtension 创建另一个值转换器实例返回?
    • 值转换器只创建一次。
    • hmm 在应用程序级别查找转换器的查找时间可能比在窗口级别实例化转换器花费的时间更长,无论如何时间可以忽略不计。但是我经常在我的转换器上使用属性来自定义给定上下文中的用法,所以我更喜欢后者。
    【解决方案2】:

    我有一个 ResourceDictionary,它声明了几个常用的转换器,例如 bool-to-visibility 转换器。我在 App.xaml 中直接引用了这本字典。

    我在页面/窗口级别(或在页面/窗口引用的 ResourceDictionary 中)声明更特定于给定情况的其他转换器。

    我无法明确回答性能问题,但如果它在加载时间或内存使用方面产生实际差异,我会感到非常惊讶。声明转换器基本上是一个对象实例化,因此它应该非常高效并且使用很少的内存,但我没有进行任何分析来比较应用级和窗口级的性能。

    【讨论】:

    • 那是我的问题...如果您知道性能答案,请不要忘记回来。
    【解决方案3】:

    如果您只需要一个窗口的转换器,我会将它用于一个窗口(或者甚至只用于包含使用它的控件的容器控件)。

    我认为这更易于维护 - 您可以查看转换器声明并了解它的用途。您知道,如果您更改该特定页面上的控件以不再使用转换器,您可以将其从页面资源中取出,而不会影响其他任何内容。相反,如果转换器是应用程序资源,那么确定正在使用它的对象就不是那么简单了。

    如果同一转换器被多个页面使用,我会仍然将它放在每个页面资源下。实际上,这只是 XAML 中的额外一行。

    无论如何,这是我的观点,截至今天。我期待另一篇文章提出完全相反的观点。 :-)

    【讨论】:

    • 没有这样的运气。我的答案一半相反,一半相同:-P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2018-03-06
    • 1970-01-01
    • 2023-03-21
    • 2020-09-28
    • 2015-09-04
    • 1970-01-01
    相关资源
    最近更新 更多