在WPF应用程序中声明转换器时,我应该:
- 将所有的转换器声明在App.xaml中(即在
<Application.Resources/>
中),以便整个应用程序都可以使用它。 - 仅在每个
Page
/Window
/ResourceDictionary
/UserControl
等的Resources
部分中声明所需的转换器。 - 完全使用其他方法
关于可读性,我认为方法1是最好的,但我的问题是关于性能的。哪种方法在性能、内存等方面最有效率?
在WPF应用程序中声明转换器时,我应该:
<Application.Resources/>
中),以便整个应用程序都可以使用它。Page
/Window
/ResourceDictionary
/UserControl
等的Resources
部分中声明所需的转换器。关于可读性,我认为方法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线程中学习来的。
如果您只需要一个窗口的转换器,我会将其放在该窗口上(甚至仅放在容器控件上,该控件包含使用它的控件)。
我认为这样更易于维护 - 您可以查看转换器声明并能够知道谁在使用它。您知道,如果您更改了特定页面上的控件以不再使用转换器,则可以从页面资源中删除它而不影响其他任何内容。相反,如果转换器是应用程序资源,则不那么容易确定是否有任何东西在使用它。
如果同一转换器被多个页面使用,我仍然会将其放在每个页面资源下面。实际上,在XAML中只需要额外添加一行。
无论如何,这是我今天的观点。我期待着另一篇文章提出完全相反的观点。 :-)
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()];
}
}