Как присвоить несколько значений перечисления свойству в конфигурации Spring.NET?

.NET поддерживает FlagsAttribute для перечисления, что означает " что перечисление можно рассматривать как битовое поле».

Примером перечисления, использующего этот атрибут [Flags], является Система.Windows.Forms.Keys

Вот мое определение объекта Spring.NET:

<object id="command.paste" type="MyNamespace.PasteClipboardCommand, MyProject">
  <property name="Title" value="Paste into Folder" />
  <property name="ShortcutKeys" value="P" />
</object>

Это устанавливает для свойства ShortcutKeys типа Keys ключ P. Никаких проблем. Однако, поскольку это ярлык, я бы хотел назначить что-то вроде Control + P в качестве сочетания клавиш.

Если бы я подключил это в коде, это было бы:

command.ShortcutKeys = Keys.Control | Keys.P;

Итак, возможно, я был немного наивен, пытаясь это:

<property name="ShortcutKeys" value="Control|P" />

Это не удается, потому что EnumConverter может анализировать/преобразовывать строковые представления только одного перечисления. Полная трассировка стека доступна ниже.

  • Возможно ли это по умолчанию Spring.NET?
  • Могу ли я обойти это, указав/используя другой EnumConverter?
  • Должен ли я создать/использовать другой класс Keys для инициализации Spring.NET?

ОБНОВЛЕНИЕ:

Очевидно, KeysConverter знает, как справиться с этим следующим образом:

(new KeysConverter()).ConvertFrom(null, null, "Control+P");

К сожалению, EnumConverter не поддерживает это?

Прикрепленная трассировка стека:

System.Configuration.ConfigurationErrorsException: Error creating context 'spring.root': PropertyAccessExceptionsException (1 errors); nested PropertyAccessExceptions are: 
[Spring.Core.TypeMismatchException: Cannot convert property value of type [System.String] to required type [System.Windows.Forms.Keys] for property 'ShortcutKeys'., Inner Exception: System.FormatException: Control|P is not a valid value for Keys. ---> System.ArgumentException: Requested value 'Control|P' was not found.
    at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
    at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    --- End of inner exception stack trace ---
    at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    at System.ComponentModel.TypeConverter.ConvertFromInvariantString(String text)
    at Spring.Core.TypeConversion.TypeConversionUtils.ConvertValueIfNecessary(Type requiredType, Object newValue, String propertyName)] ---> Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'command.builder.paste' defined in 'file [....\commands.xml] line 39' : Error setting property values: PropertyAccessExceptionsException (1 errors); nested PropertyAccessExceptions are: 
[Spring.Core.TypeMismatchException: Cannot convert property value of type [System.String] to required type [System.Windows.Forms.Keys] for property 'ShortcutKeys'., Inner Exception: System.FormatException: Control|P is not a valid value for Keys. ---> System.ArgumentException: Requested value 'Control|P' was not found.
    at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
    at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    --- End of inner exception stack trace ---
    at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    at System.ComponentModel.TypeConverter.ConvertFromInvariantString(String text)
    at Spring.Core.TypeConversion.TypeConversionUtils.ConvertValueIfNecessary(Type requiredType, Object newValue, String propertyName)] ---> PropertyAccessExceptionsException (1 errors); nested PropertyAccessExceptions are: 
[Spring.Core.TypeMismatchException: Cannot convert property value of type [System.String] to required type [System.Windows.Forms.Keys] for property 'ShortcutKeys'., Inner Exception: System.FormatException: Control|P is not a valid value for Keys. ---> System.ArgumentException: Requested value 'Control|P' was not found.
    at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
    at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    --- End of inner exception stack trace ---
    at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
    at System.ComponentModel.TypeConverter.ConvertFromInvariantString(String text)
    at Spring.Core.TypeConversion.TypeConversionUtils.ConvertValueIfNecessary(Type requiredType, Object newValue, String propertyName)]

person toong    schedule 04.08.2011    source источник
comment
Не решение, а обходной путь - хранить базовое числовое значение, а не само перечисление.   -  person InBetween    schedule 04.08.2011
comment
Хорошая находка - вы можете опубликовать ответ на свой вопрос и принять его, но только через сутки. Пожалуйста, сделайте это позже, чтобы мы все увидели, что ваша проблема решена, и тоже проголосовали за ваш ответ ;-)   -  person Marijn    schedule 04.08.2011
comment
Спасибо, завтра выложу. На самом деле я нашел функцию «+» для KeysConverter, просмотрев исходный код моно.   -  person toong    schedule 04.08.2011
comment
Опубликовал свой собственный ответ ниже сейчас :-)   -  person toong    schedule 08.08.2011
comment
Я дам @bbaia немного больше времени, чтобы предоставить дополнительную информацию для решения проблем с его ответом.   -  person toong    schedule 08.08.2011


Ответы (2)


Если вы посмотрите документацию Spring.NET 5.11 Конфигурация IApplicationContext вы можете увидеть пример того, как добавить конкретный преобразователь типа для данного типа.

Достаточно добавить KeysConverter для типа Keys в app.config:

<converter for="System.Windows.Forms.Keys, System.Windows.Forms" type="System.Windows.Forms.KeysConverter, System.Windows.Forms"/>

Теперь enumvalue/ярлык можно указать так:

<property name="ShortcutKeys" value="Control+P" />
person toong    schedule 08.08.2011
comment
Хороший! Не думал об этом! - person bbaia; 06.09.2011

Попробуйте использовать SpEL (язык выражений Spring.NET): http://www.springframework.net/doc-latest/reference/html/expressions.html

<property name="ShortcutKeys" expression="Keys.Control or Keys.P" />

or

<property name="ShortcutKeys" expression="T(System.Windows.Forms.Keys).Control or T(System.Windows.Forms.Keys).P" />
person bbaia    schedule 04.08.2011
comment
Первый вариант завершается с ошибкой: Ошибка инициализации объекта: не удается инициализировать свойство или узел поля «Ключи», поскольку указанный контекст имеет значение null. ---› Spring.Core.NullValueInNestedPathException: невозможно инициализировать свойство или узел поля «Ключи», поскольку указанный контекст имеет значение null. - person toong; 05.08.2011
comment
Второй вариант завершается с ошибкой: Ошибка инициализации объекта: не удалось загрузить тип из строкового значения «System.Windows.Forms.Keys.Control». ---› System.TypeLoadException: Не удалось загрузить тип из строкового значения «System.Windows.Forms.Keys.Control». - person toong; 05.08.2011
comment
Первый вариант терпит неудачу, потому что перечисление Keys не находится в mscorlib, вы должны зарегистрировать его в Spring TypeRegistry, см. документы. - person Marijn; 16.08.2011
comment
Я отредактировал ответ; второй вариант больше не проходит мой тест. - person Marijn; 24.08.2011