首页 > 解决方案 > 为每个 ListBox 项实例化一个新的 ValueConverter 实例

问题描述

我已经定义了以下枚举来表示我的程序中的位域:

[Flags]
public enum CXIOByte
{
    None = 0,
    Bit0 = 1,
    Bit1 = 2,
    Bit2 = 4,
    Bit3 = 8,
    Bit4 = 16,
    Bit5 = 32,
    Bit6 = 64,
    Bit7 = 128
}    

在运行时,我创建了一个 CXIOByte 类型的实例列表(封装在一个 CXIOByte 实例名为 Value 的类中),它们在我的 XAML 中表示为一组复选框:

ListBox ItemsSource="{Binding InputItems}">
<ListBox.ItemTemplate>
    <DataTemplate DataType="models:CXInputOutputModel">
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit0}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit1}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit2}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit3}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit4}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit5}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit6}}" Margin="5"/>
            <CheckBox IsChecked="{Binding Path=Value, Converter={StaticResource enumBitfieldValueConverterI}, ConverterParameter={x:Static models:CXIOByte.Bit7}}" Margin="5"/>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

我有一个 IValueConverter 有助于评估字段中单个位的“已检查”状态:

public class EnumBitfieldValueConverter : IValueConverter
{
    private int targetValue;

    public EnumBitfieldValueConverter()
    {
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int mask = (int)parameter;
        targetValue = (int)value;

        return ((mask & targetValue) != 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        targetValue ^= (int)parameter;
        return Enum.Parse(targetType, targetValue.ToString());

    }
}

此 IValueConverter 的实例使用内部“targetValue”属性跟踪运行时值。

现在,这适用于 ListView 中的单个 InputItem。但是,如果我在 ListView 中有多个 InputItem,我需要每个项目使用它自己的 IValueConverter 实例。否则,每个项目都会干扰前一个项目的目标值。

有没有办法做到这一点?

标签: c#wpfxamlivalueconverter

解决方案


将转换器声明为非共享资源:

<local:EnumBitfieldValueConverter x:Key="enumBitfieldValueConverterI" x:Shared="False">

{StaticResource}每次都会返回新实例


推荐阅读