在IValueConverter类中定义属性

时间:2015-01-25 21:33:36

标签: wpf dependency-properties ivalueconverter

我需要在转换器类中定义DependencyProperty,因为我需要这些数据来进行转换,而这些数据在另一个对象中,而不是我绑定的对象。

我的转换器类如下:

public class LEGOMaterialConverter   : DependencyObject, IValueConverter
{
    public DependencyProperty MaterialsListProperty = DependencyProperty.Register("MaterialsList", typeof(Dictionary<int, LEGOMaterial>), typeof(LEGOMaterialConverter));

    public Dictionary<int, LEGOMaterial> MaterialsList
    {
        get
        {
            return (Dictionary<int, LEGOMaterial>)GetValue(MaterialsListProperty);
        }
        set
        {
            SetValue(MaterialsListProperty, value);
        }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        LEGOMaterial material = null;

        MaterialsList.TryGetValue((int)value, out material);

        return material;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然后我在Window.REsources区域实现它:

<Window.Resources>
    <local:LEGOMaterialConverter x:Key="MaterialsConverter" MaterialsList="{Binding Path=Materials}" />
</Window.Resources>

我收到以下错误:

   'MaterialsList' property was already registered by 'LEGOMaterialConverter'.

有没有人对这个错误有所了解?

2 个答案:

答案 0 :(得分:6)

尝试这样做(只是一个例子):

public class ValueConverterWithProperties : MarkupExtension, IValueConverter
{
    public int TrueValue { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((int) value == TrueValue)
        {
            return true;
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

注意我从标记扩展派生,允许我像这样使用它:

<Window x:Class="Converter.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converter="clr-namespace:Converter"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <CheckBox IsChecked="{Binding item, Converter={converter:ValueConverterWithProperties TrueValue=5}}"></CheckBox>
    <CheckBox IsChecked="{Binding item2, Converter={converter:ValueConverterWithProperties TrueValue=10}}"></CheckBox>
</Grid>

答案 1 :(得分:4)

顺便说一下,这个错误是由转换器中的依赖属性不是静态的(以及之前在某处创建了这个转换器的实例)引起的。

修改

问题在于这一行:

public DependencyProperty MaterialsListProperty = DependencyProperty.Register("MaterialsList", typeof(Dictionary<int, LEGOMaterial>), typeof(LEGOMaterialConverter));

此处,依赖属性MaterialsListProperty正在使用此类型的对象的每个实例注册(即LEGOMaterialConverter)。

但是依赖属性应该是静态定义的,如下所示:

public static readonly DependencyProperty MaterialsListProperty = DependencyProperty.Register("MaterialsList", typeof(Dictionary<int, LEGOMaterial>), typeof(LEGOMaterialConverter));

静态变量只为此类型的所有未来实例初始化(并且已注册Dependency属性),这就是我们在此需要的。未将依赖属性声明为静态会导致上述错误。