Должен ли я объявлять конвертеры в App.xaml или в качестве ресурса для каждого файла?

При объявлении преобразователей в приложении WPF следует:

  • Объявите все мои конвертеры в App.xaml(т.е. в <Application.Resources/>), чтобы он был доступен для всего приложения
  • Объявить только необходимые конвертеры для каждого Page/Window/ResourceDictionary/UserControl и т.д. в разделе Resources
  • Что-то еще полностью

Что касается читаемости, метод 1 кажется мне лучшим, но мой вопрос касается производительности. Какой метод является наиболее ресурсоэффективным с точки зрения производительности, памяти и т.д.?

Ответ 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}}"

где преобразователи - это пространство имен, в котором я объявил свой конвертер.

Выучил этот трюк только из потока старых потоков stackoverflow.

Ответ 2

У меня есть ResourceDictionary, который объявляет несколько часто используемых конвертеров, таких как конвертер bool-to-visibility. Я ссылаюсь на этот словарь непосредственно в App.xaml.

Я объявляю другие конвертеры, которые более специфичны для данной ситуации на уровне страницы/окна (или в ResourceDictionary, на который ссылается страница/окно).

Я не могу ответить на вопрос об эффективности окончательно, но я был бы очень удивлен, если бы он сделал практическую разницу в времени загрузки или использовании памяти. Объявление конвертера в основном является созданием объекта, поэтому оно должно быть очень эффективным и использовать очень мало памяти, но я не делал профилирования для сравнения производительности на уровне приложений и уровня окна.

Ответ 3

Если вам нужен конвертер только для одного окна, я бы поставил его для одного окна (или даже для элемента управления контейнера, который содержит элемент управления, который его использует).

Я бы сказал, что это более удобно: вы можете посмотреть объявление конвертера и узнать, что его использует. Вы знаете, что если вы измените элементы управления на этой конкретной странице, чтобы больше не использовать конвертер, вы можете извлечь его из ресурсов страницы, не затрагивая ничего другого. И наоборот, если конвертер является ресурсом приложения, не так просто определить, что его использовать, если что-либо.

Если один и тот же конвертер используется более чем на одной странице, я бы еще помещал его под каждый ресурс страницы. Действительно, это только одна дополнительная строка в XAML.

Во всяком случае, это мое мнение, на сегодняшний день. Я ожидаю, что еще одна статья будет прямо противоположной.: -)