Проблема инициализации коллекционного свойства-время разработки
Я создал свойство, которое представляет собой набор объектов с пользовательским
UITypeEditor
для коллекции, а также TypeConverter
на объекты. Все, кажется, работает нормально, за исключением того, что если я войду и отредактирую коллекцию в дизайнере во 2-й или последующий раз, новые значения коллекции не будут инициализированы.Я думаю, что важными битами моего кода являются:
Свойство коллекции:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [Editor(typeof(FileTypeEditor), typeof(UITypeEditor))] public FileTypes FileTypes { get; internal set; } = new FileTypes();
Элемент сбора:
[Serializable] [TypeConverter(typeof(FileTypeConverter))] public class FileType { internal FileType() { } public FileType(string description, string filter) { Description = description; Filter = filter; } // ...
То
TypeConverter
class FileTypeConverter : TypeConverter { static Regex srch = new Regex(@"^(.*)\s\((.*)\)$", RegexOptions.Compiled); public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) return true; return base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string) || destinationType == typeof(InstanceDescriptor)) return true; return base.CanConvertTo(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { try { Match m = srch.Match((string)value); return new FileType(m.Groups[1].Value, m.Groups[2].Value); } catch { return new FileType(); } } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (value is FileType) { FileType ft = (FileType)value; if (destinationType == typeof(string)) { return $"{ft.Description} ({ft.Filter})"; } if (destinationType == typeof(InstanceDescriptor)) { return new InstanceDescriptor(typeof(FileType).GetConstructor(new[] { typeof(string), typeof(string) }), new object[] { ft.Description, ft.Filter }); } } return base.ConvertTo(context, culture, value, destinationType); } }
То
UITypeEditor
public class FileTypeEditor : UITypeEditor { IWindowsFormsEditorService _editorService; public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.Modal; } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { if (provider != null) { _editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; if (_editorService != null) { using (FileTypeEditorForm frm = new FileTypeEditorForm((FileTypes)value, _editorService)) { if (_editorService.ShowDialog(frm) == DialogResult.OK) { return frm.FileTypes; } } } } return value; } }
Сгенерированный код инициализации после первого редактирования свойства:
this.fileOpenDialog1.FileTypes.AddRange(new CommonItemDialog.FileType[] { new CommonItemDialog.FileType("All Files", "*.*"), new CommonItemDialog.FileType("Audio Files", "*.m4a;*.mp3;*.wav;*.wma")});
И все это прекрасно. Эта проблема возникает только в том случае, если я иду и меняю коллекцию - добавляю новый элемент или меняю элемент, эта инициализация не изменяется, чтобы отразить отредактированную коллекцию.
Что я здесь упускаю? Я в полном отчаянии.
Что я уже пробовал:
Поиск в google, чтение тонн статей (включая, но не ограничиваясь CP здесь[^] и здесь[^])- Я просто не вижу, чего мне здесь не хватает.
Midi_Mick
Ну, я обошел эту проблему, сделав коллекцию массивом и выполнив стандартную сериализацию (я полностью избавился от TypeConverter). Тем не менее, я все еще очень хотел бы знать, почему структура, которую я использовал, терпела неудачу.