【问题标题】:Defining a Property in a IValueConverter class在 IValueConverter 类中定义属性
【发布时间】:2015-03-24 08:59:02
【问题描述】:

我需要在转换器类中定义一个 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'.

有人知道这个错误吗?

【问题讨论】:

标签: wpf dependency-properties ivalueconverter


【解决方案1】:

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

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>

【讨论】:

  • 似乎解决了我的问题,但在您的情况下,传递数据很容易,您在 XAML 中键入整数值。我如何将字典传递给转换器?
  • 字典里有什么?是静态的吗?它是动态的吗?
  • 这是我的一个类的属性,它被加载了一次,之后它就不再改变了。但它只有在表单加载后才设置...
  • 如果它被加载一次并且从未改变,不能将它设置为转换器的静态属性吗?
  • 也许吧,但由于我只能在表单加载后才能加载数据,所以我不知道该怎么做。如果我将它设置为静态资源,它会在解析 XAML 时实例化它,对吧?
【解决方案2】:

顺便说一句,这个错误是由于你在转换器中的依赖属性不是静态的(并且在之前的某个地方创建了这个转换器的实例之后)。

编辑

所以问题出在这一行:

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));

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

【讨论】:

    猜你喜欢
    • 2012-04-16
    • 2014-09-29
    • 1970-01-01
    • 2012-01-25
    • 2013-08-23
    • 2016-05-03
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    相关资源
    最近更新 更多