2011-01-21 2 views
4

После прочтения некоторых из msdn docs я подумал, что я понял, как использовать настраиваемый тип в качестве настройки приложения с помощью визуального дизайнер-студии.ошибка с использованием преобразователя типа для настройки приложения

Дизайнер хранит мою строку достаточно счастливо, но я получаю сообщение об ошибке, когда я запускаю модульный тест, чтобы проверить, могу ли я действительно использовать параметр.

Я получал ошибки сериализации на некоторых других типах, которые составляют особый тип, о котором идет речь, - я заставил их уйти, неохотно сделав публикацию нескольких свойств сеттерами. НО ДОКУМЕНТЫ ПРЕДУПРЕЖДАЮТ, что если будет установлен конвертер типов, он будет использоваться вместо сериализации. Должен ли я предоставлять конвертер типов для каждого типа, который составляет тип, который я хочу в качестве параметра?

Приветствия,
Berryl

сгенерированный код от дизайнера установки

[global::System.Configuration.ApplicationScopedSettingAttribute()] 
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
[global::System.Configuration.DefaultSettingValueAttribute("8 hours")] 
public global::Smack.Core.Lib.Domains.Temporal.TimeQuantity WorkQuota_Daily { 
    get { 
     return ((global::Smack.Core.Lib.Domains.Temporal.TimeQuantity)(this["WorkQuota_Daily"])); 
     } 
    } 

модульного теста и ошибок

[Test] 
    public void WorkQuota_Daily_CanRead() { 
     var setting = Properties.Settings.Default.WorkQuota_Daily; 
     Assert.That(setting, Is.EqualTo(TimeQuantity.Hours(8))); 
    } 
Test failed: System.ArgumentException : The property 'WorkQuota_Daily' could not be created from it's default value. 
Error message: There is an error in XML document (1, 1). 
at System.Configuration.SettingsPropertyValue.Deserialize() 
at System.Configuration.SettingsPropertyValue.get_PropertyValue() 
at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName) 
at System.Configuration.SettingsBase.get_Item(String propertyName) 
at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName) 
at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName) 
C:\Users\Lord & Master\Documents\Projects\Smack\trunk\src\ConstructionAdmin.TestingSupport\Properties\Settings.Designer.cs(211,0): at Smack.ConstructionAdmin.TestingSupport.Properties.Settings.get_WorkQuota_Daily() 
General\ApplicationSettingsTests.cs(22,0): at Smack.ConstructionAdmin.TestingSupport.General.ApplicationSettingsTests.WorkQuota_Daily_CanRead() 

преобразователь типа

public class TimeQuantityTypeConverter : TypeConverter 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     if (value is string) 
     { 
      var v = ((string)value).Split(); 
      var amt = v[0]; 
      var unit = v[1]; 
      var timeSliceFactory = new TimeSliceFactory(); 
      var map = TimeSliceFactory.GetUnitMap(timeSliceFactory); 
      var key = unit.ToLowerInvariant(); 
      if (!map.ContainsKey(key)) throw new ArgumentException(string.Format("There is no time slice unit key fpr '{0}", key)); 
      return new TimeQuantity(amt, map[key]); 
     } 
     return base.ConvertFrom(context, culture, value); 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
    { 
     if (destinationType == typeof(string)) { 
      return string.Format("{0} {1}", ((TimeQuantity) value).Amount, ((TimeQuantity) value).Unit.PluralForm); 
     } 
     return base.ConvertTo(context, culture, value, destinationType); 
    } 
} 

настройки файла (несколько настроек пользователя) опущен

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 
public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 

    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 

    public static Settings Default { 
     get { 
      return defaultInstance; 
     } 
    } 

    [global::System.Configuration.ApplicationScopedSettingAttribute()] 
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
    [global::System.Configuration.DefaultSettingValueAttribute("8 hours")] 
    public global::Smack.Core.Lib.Domains.Temporal.TimeQuantity WorkQuota_Daily { 
     get { 
      return ((global::Smack.Core.Lib.Domains.Temporal.TimeQuantity)(this["WorkQuota_Daily"])); 
     } 
    } 

    [global::System.Configuration.ApplicationScopedSettingAttribute()] 
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
    [global::System.Configuration.DefaultSettingValueAttribute("Monday")] 
    public global::System.DayOfWeek StartDay { 
     get { 
      return ((global::System.DayOfWeek)(this["StartDay"])); 
     } 
    } 
} 

Update (Fixed!)

ответа переходит к первому человеку, который видит, что часть головоломки я отсутствовал. Подсказка №1 - оригинальный код TypeConverter был в порядке. Подсказка # 2 - System.ComponentModel довольно мощный!

+0

Как выглядит ваш файл настроек? –

+0

@ Chris. В конце моего сообщения я опубликовал больше сгенерированного кода, а также мое последнее изменение в TypeConverter для использования экземпляра InstanceDescriptor. Другие параметры в файле настроек можно использовать. – Berryl

+0

@ Крис. Нет, я не хочу InstanceDescriptor в конце концов. Вернемся к исходному коду и ошибке. Grrr – Berryl

ответ

2

@Berryl - Я получил эту работу (с некоторыми изменениями, например, с созданием собственного класса TimeQuantity). Не помните ли вы добавить TypeConverterAttribute в свой класс TimeQuantity?

[TypeConverter(typeof(TimeQuantityTypeConverter))] 
public class TimeQuantity 
{ 

Если установить контрольную точку внутри вашей CanConvertFrom (...) и ConvertFrom (...) методы, вы должны видеть, что они попали, когда вы читаете свойство. Без этого атрибута TypeConverter я получаю ту же самую ошибку.

+0

Да, холмс. Атрибут был тем, что мне не хватало. Ура! – Berryl

Смежные вопросы