【问题标题】:My custom value converter causes XAML validation tool to fail我的自定义值转换器导致 XAML 验证工具失败
【发布时间】:2015-04-24 19:14:50
【问题描述】:

我创建了一个自定义转换器,它根据配置的映射执行值转换。如下图所示

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) { }
}

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>

现在一切都构建并运行良好,但如果我使用它,XAML Visual Studio 会用弯曲的蓝线强调整个文件并显示两种错误:

1) 如果转换器被放入ResourceDictionary 并且被分配一个x:Key 属性它显示Missing key value on 'UniversalConverter' object

2) 如果我为DefaultValue 属性分配任何值(例如{x:Null}),则消息为XAML Node Stream: Missing EndMember for 'StuffLib.UniversalConverter.{http://schemas.microsoft.com/winfx/2006/xaml}_Items' before StartMember 'StuffLib.UniversalConverter.DefaultValue'

这些消息的原因是什么?我可以忍受它们,但它们隐藏了所有其他编译器和 ReSharper 标记

【问题讨论】:

  • 能否请您发布您的 XAML 代码?
  • 您需要分享完整代码,否则我们无法判断错误在哪里
  • @Dominik 这对我使用的转换逻辑没有任何影响。即使我只是写return DependecyProperty.UnsetValue 我仍然看到这个下划线
  • 请向我们展示 XAML 以及您的值转换器的实现。由于您在正确处理其中一项或两项时遇到问题,因此可能会影响您的代码外观。否则我们只有你当前的分析可以继续,这还不够——如果是这样,你一开始就不会在这里。
  • @stakx 添加了完整的代码和示例 XAML

标签: c# wpf xaml ivalueconverter


【解决方案1】:

不要从列表继承,只需在转换器中创建 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="..." />

【讨论】:

  • 我接受这个答案,因为它让我看起来正确。有关详细信息和编辑,请参阅下面我自己的答案。我会在 22 小时内奖励赏金
  • 我仍然不知道为什么从列表继承会导致这个错误,但这解决了我在设计器中的 NullReferenceExceptions 问题。 @Demarsch 在他的附加答案中的代码甚至使 XAML 代码看起来一样。
【解决方案2】:

基于@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
}

请注意,这样您就不需要在 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>

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 没用。我什至从Convert() 方法中删除了所有代码并将return null; 放在那里。也没有用
    • 尝试对 Convert 和 ConvertBack 使用 DependencyProperty.UnsetValue 而不是 null。
    猜你喜欢
    • 1970-01-01
    • 2019-11-11
    • 2021-06-03
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2020-07-22
    • 1970-01-01
    相关资源
    最近更新 更多