2015-04-24 6 views
2

Я создал собственный конвертер, который выполняет преобразование значений на основе настроенного сопоставления. Это выглядит, как показано нижеМой преобразователь настраиваемых значений приводит к сбою инструмента проверки XAML

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.

+1

Не могли бы вы опубликовать свой код XAML? – Domysee

+1

Вам нужно разделить полный код, иначе мы не сможем определить, где ошибка – Liero

+0

@ Dominik действительно не имеет значения, какую логику преобразования я использую. Даже если я просто напишу 'return DependecyProperty.UnsetValue', я все еще вижу это подчеркивание – Demarsch

ответ

3

Не унаследован из списка, просто создать 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="..." /> 
+0

Я принимаю этот ответ, потому что это заставило меня выглядеть правильно. См. Мой собственный ответ ниже для подробностей и изменений.Я получу награду за 22 часа – Demarsch

+0

Я до сих пор не знаю, почему наследование из списка вызывает эту ошибку, но это решает мою проблему с NullReferenceExceptions в дизайнере. Код от @Demarsch в его дополнительном ответе даже делает код XAML одинаковым. – linac

0

Это потому, что он используется во время разработки, но данных нет, поэтому я подозреваю, что возникает исключение NullReferenceException. Попробуйте проверить в режиме времени проектирования следующим образом в верхней части IValueConverter.Convert() тела метода:

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

Не работает. Я даже удалил весь код из 'Convert()' метода и поставил 'return null ;, там. Не работает либо – Demarsch

+0

Попробуйте использовать DependencyProperty.UnsetValue для Convert и ConvertBack вместо null. –

+0

Не помогло ( – Demarsch

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>