C# 我的自定义值转换器导致XAML验证工具失败

C# 我的自定义值转换器导致XAML验证工具失败,c#,wpf,xaml,ivalueconverter,C#,Wpf,Xaml,Ivalueconverter,我创建了一个自定义转换器,它根据配置的映射执行值转换。它看起来像下面 public class UniversalConverter : List<ConverterItem>, IValueConverter { private bool useDefaultValue; private object defaultValue; public object DefaultValue { get { return defaultVa

我创建了一个自定义转换器,它根据配置的映射执行值转换。它看起来像下面

public class UniversalConverter : List<ConverterItem>, IValueConverter
{
    private bool useDefaultValue;

    private object defaultValue;

    public object DefaultValue
    {
        get { return defaultValue; }
        set
        {
            defaultValue = value;
            useDefaultValue = true;
        }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var item in this)
            if (Equals(item.From, value))
                return item.To;
        if (useDefaultValue)
            return DefaultValue;
        throw new ConversionException(string.Format("Value {0} can't be converted and default value is not allowed", value));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var item in this)
            if (Equals(item.To, value))
                return item.From;
        throw new ConversionException(string.Format("Value {0} can't be converted back", value));
    }
}

public class ConverterItem
{
    public object From { get; set; }

    public object To { get; set; }
}

public class ConversionException : Exception
{
    public ConversionException() { }

    public ConversionException(string message) : base(message) { }
}
公共类通用转换器:列表,IValueConverter
{
私有布尔值;
私有客体价值;
公共对象默认值
{
获取{return defaultValue;}
设置
{
默认值=值;
useDefaultValue=true;
}
}
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
foreach(本文件中的var项目)
如果(等于(项目、起始、值))
将项目返回至;
如果(使用默认值)
返回默认值;
抛出新的ConversionException(string.Format(“无法转换值{0},不允许使用默认值”,Value));
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
foreach(本文件中的var项目)
如果(等于(项到值))
返回项目。从;
抛出新的ConversionException(string.Format(“值{0}无法转换回”,Value));
}
}
公共类转换器项
{
来自{get;set;}的公共对象
公共对象{get;set;}
}
公共类ConversionException:异常
{
公共ConversionException(){}
公共转换异常(字符串消息):基(消息){}
}
样本XAML如下所示

<core:UniversalConverter x:Key="ItemCountToVisiblityConverter" DefaultValue="{x:Static Visibility.Collapsed}">
    <core:ConverterItem To="{x:Static Visibility.Visible}">
        <core:ConverterItem.From>
            <system:Int32>0</system:Int32>
        </core:ConverterItem.From>
    </core:ConverterItem>
</core:UniversalConverter>

0
现在,一切都可以正常构建和工作,但如果我使用它,XAML Visual Studio会用蓝色曲线突出整个文件,并显示两种错误:

1) 如果转换器被放入
ResourceDictionary
,并被分配了
x:Key
属性,则它会在“UniversalConverter”对象上显示
缺少的键值

2) 如果我为
DefaultValue
属性分配任何值(例如
{x:Null}
),则消息是
XAML节点流:缺少'StuffLib.UniversalConverter'的EndMember{http://schemas.microsoft.com/winfx/2006/xaml}_Items'before StartMember'StuffLib.UniversalConverter.DefaultValue'


这些信息的原因是什么?我可以使用它们,但它们隐藏了所有其他编译器和重新精简标记

这是因为它在设计时使用,但没有数据,所以我怀疑抛出了NullReferenceException。在IValueConverter.Convert()方法主体的顶部尝试检查设计时模式,如下所示:

// Check for design mode. 
if ((bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)) 
{
    return false;
}

不从列表继承,只在转换器中创建Items属性:

[ContentProperty("Items")]
public class UniversalConverter : IValueConverter
{
    public ConverterItem[] Items { get; set; }

    public object DefaultValue { get; set; }
    //all other stuff goes here
}
和xaml:

<l:UniversalConverter x:Key="MyConverter">
  <x:Array Type="l:ConverterItem">
    <l:ConverterItem From="..." To="..." />

基于@Leiro给出的答案

[ContentProperty("Items")]
public class UniversalConverter : IValueConverter
{
    public UniversalConverter()
    {
        Items = new List<ConverterItem>();
    }

    public List<ConverterItem> Items { get; private set; } 
    //All other logic is the same
}
[ContentProperty(“项目”)]
公共类通用转换器:IValueConverter
{
公共通用转换器()
{
项目=新列表();
}
公共列表项{get;private set;}
//所有其他逻辑都是一样的
}
注意,这样您就不需要在XAML中包装集合中的项

结果XAML

<core:UniversalConverter x:Key="ItemCountToVisiblityConverter" DefaultValue="{x:Static Visibility.Collapsed}">
    <core:ConverterItem To="{x:Static Visibility.Visible}">
        <core:ConverterItem.From>
            <system:Int32>0</system:Int32>
        </core:ConverterItem.From>
    </core:ConverterItem>
</core:UniversalConverter>

0

不起作用。我甚至从
Convert()
方法中删除了所有代码,并将
返回null那里。使用Convert和ConvertBack的DependencyProperty.UnsetValue(而不是null)无法正常工作。请发布您的XAML代码好吗?您需要共享完整的代码,否则我们无法确定error@Dominik这与我使用的转换逻辑没有什么区别。即使我只是写
返回dependecProperty.unset值
我仍然看到这个下划线请给我们展示XAML和值转换器的实现。由于您在正确处理其中一个或两个方面存在问题,因此很可能会改变代码的外观。否则我们只有你当前的分析,这是不够的——如果是的话,你就不会在这里了。@stakx添加了完整的代码和示例XAMLI我接受这个答案,因为它让我看起来很正确。有关详细信息和编辑,请参见下面我自己的答案。我将在22小时后奖励bounty我仍然不知道为什么从列表继承会导致此错误,但这解决了我在设计器中出现NullReferenceException的问题。@Demarsch在其附加答案中的代码甚至使XAML代码看起来相同。