WPF每个绑定实例如何使用值转换器?

4
如何确保在每次绑定中使用的值转换器都创建了一个新实例?
5个回答

20

您需要在转换器资源上指定 x:Shared="False"。以下是示例:

<BooleanToVisibilityConverter x:Key="MyConverter" x:Shared="False"/>

3
你可以在每个控件中创建一个独立的资源:
   <TextBox>
        <TextBox.Resources>
            <Converters:VisibilityConverter x:Key="conv"/>
        </TextBox.Resources>
        <TextBox.Text>
            <Binding Converter="{StaticResource conv}"/>
        </TextBox.Text>
    </TextBox>

1

为什么?它应该是确定性的,并且不知道除通过其参数传递给它的状态之外的任何状态。我使用值转换器来保持图像的静态列表(一个值被转换为一个图像),这个方法很好用——即使在数据网格中使用相同的转换器跨越数千行时也是如此。(请注意,转换器仍然不知道任何外部状态)。

无论如何,请查看这是否回答了您的问题:WPF中的值转换器是否每绑定实例化一次?


2
我需要一个转换器来绑定两个可观察集合或略微不同的类型。我在转换器中跟踪集合更改事件。因此每个实例都需要。 - NVM

0
继承自 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}


  <CheckBox IsChecked="{Binding SomeFlagsEnum, ConverterParameter=FlagA, Converter={src:FlagsToBoolConverter}}">FlagA</CheckBox>
  <CheckBox IsChecked="{Binding SomeFlagsEnum, ConverterParameter=FlagB, Converter={src:FlagsToBoolConverter}}">FlagB</CheckBox>
  <CheckBox IsChecked="{Binding SomeFlagsEnum, ConverterParameter=FlagC, Converter={src:FlagsToBoolConverter}}">FlagC</CheckBox>

-1
如果将转换器放入资源中并通过{StaticResource ConverterName}查找引用它们,则每个资源字典实例化一次。
但更好的方法是从MarkupExtension继承您的转换器并直接使用它们,而不是将它们添加到资源中并引用它们。
以下是一个此类基类的示例:

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

你好 Christian


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接