WPF每个绑定值转换器的实例?

如何确保为其使用的每个绑定创建值转换器的新实例?

您需要在转换器资源上指定x:Shared="False" 。 这是一个例子:

  

您可以在每个控件中创建单独的资源:

          

为什么? 它应该是确定性的,并且不知道任何状态,除了通过其参数传递给它的状态。 我使用值转换器来保存静态图像列表(一个值转换为图像),这很好 – 即使在具有数千行的数据网格中的多个列上使用相同的转换器时也是如此。 (注意转换器仍然没有意识到任何外部状态)。

在任何情况下,看看这是否回答了你的问题: 在WPF中每个绑定都实例化了值转换器吗?

inheritance自MarkupExtension ,然后在构造函数中创建转换器。

  public override object ProvideValue(IServiceProvider serviceProvider) { _converter = new FlagsToBoolConverter(); return _converter; } 

这是一个完整的例子。 它是一个标志转换器,需要实例化以保持ConvertBack的源值。

 using System; using System.Globalization; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Data; using System.Windows.Markup; namespace Something { public class FlagsToBoolConverter : MarkupExtension, IValueConverter { private FlagsToBoolConverter _converter; public override object ProvideValue(IServiceProvider serviceProvider) { _converter = new FlagsToBoolConverter(); return _converter; } private ulong _sourceValue; public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture) { try { var type = value.GetType(); if (type.IsEnum) { ulong mask = (ulong)System.Convert.ChangeType(Enum.Parse(type, (string)parameter), typeof(ulong)); _sourceValue = (ulong)System.Convert.ChangeType(Enum.Parse(type, value.ToString()), typeof(ulong)); return ((mask & _sourceValue) != 0); } return value; } catch (Exception ex) { Console.WriteLine("FlagsEnumValueConverter: Invalid Cast(to) Value={0} Type={1} Param={2} Exception{3}", value, targetType, parameter, ex); } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { try { if (targetType.IsEnum) { var original = this._sourceValue; var originalEnum = Enum.Parse(targetType, original.ToString()); var maskEnum = Enum.Parse(targetType, (string)parameter); var mask = (ulong)System.Convert.ChangeType(maskEnum, typeof(ulong)); _sourceValue ^= mask; var sourceEnum = Enum.Parse(targetType, _sourceValue.ToString()); Console.WriteLine($"Modified Value: {original} ({originalEnum}) by Mask {mask} ({maskEnum}) Result = {_sourceValue} ({sourceEnum})"); return sourceEnum; } return value; } catch (Exception ex) { Console.WriteLine("FlagsEnumValueConverter: Invalid Cast(from) Value={0} Type={1} Param={2} Exception{3}", value, targetType, parameter, ex); } return value; } } } 

您的前缀需要声明为xmlns:src="clr-namespace:Something" 。 然后在你的绑定中用Converter={src:FlagsToBoolConverter}替换普通的转换Converter={src:FlagsToBoolConverter}

  FlagA FlagB FlagC 

如果将转换器放入资源并通过{StaticResource ConverterName}查找引用它们,则它们仅在每个资源字典实例中实例化一次。

但更好的方法是从MarkupExtensioninheritance转换器并直接使用它们,而不是将它们添加到资源并引用它们。

以下是此类基类的示例:

http://www.snippetsource.net/Snippet/18/base-class-for-valueconverters-in-wpf

问候基督徒