Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Хранение preset-ов в setting-ах

4 комментария

Сегодня я зарелизил версию 1.7.2 Типографикса, добавив всего одну фичу – возможность держать несколько наборов настроек. Сделал я это для того, чтобы можно было сохранять настройки редактора для разных платформ – в моем случае, для этого блога и devtalk, а также для Хабра, ГДН, CodeProject’а и других систем.

Примечательно то, что простенькая задача сохранить в словарике несколько пресетов и потом записать все это в Properties.Settings превратилась в непростую затею.

Первая попытка

Сначала я сделал все правильно: создал Dictionary<string, ConversionOptions>, то есть мэп названий пресетов на их значения, и тупо попробовал записать все это в настройки. Ничего не получилось. Оказывается, большое количество классов в WPF (такие как Color или Thickness) не сериализуются! Это значит, что по сути дела чтобы сериализовать тип мне нужно их выкинуть!

Следующей проблемой оказалось то, что .Net бросал исключение при попытке сериализовать событие PropertyChanged. Это правда очень быстро релилось прописыванием [field: NonSerialized], но толком делу не помогло.

Вторая попытка

Проблема в том, что несмотря на то, что все работало, настройки отказались записывать Dictionary<>. Никаких исключений не было, тип просто не сохранялся в Properties.Settings и воответственно при попытке считать, возвращался null.

Самое простое в этом случае (точно так же как и в случае с несериализуемыми типами) – это сконвертировать структуру не в XML а в… JSON! (Формат выбран произвольно.) Соответственно, я скачал ServiceStack.Text и заменил тип свойств в Settings на string. В результате, сериализация происходит вот так:

Settings.Default["OptionPresets"] =
  JsonSerializer.SerializeToString(OptionPresets, typeof (Dictionary<string, ConversionOptions>));

Ну а что касается тех «несериализуемых» полей то, увы, приходится делать строковые или аналогичные backing fields, со всемы вытекающими последствиями.

Advertisements

Written by Dmitri

5 июня 2011 в 23:22

Опубликовано в .NET, C#

комментария 4

Subscribe to comments with RSS.

  1. Дмитрий, возможно, стоило попробовать сериализацию в Xaml (см. XamlServices). Она бы справилась с сериализацией WPF-объектов.

    Михаил

    6 июня 2011 at 20:06

    • Спасибо, гляну. На самом деле в моей программе сериализация используется для deep copy объекта. Используется там BinaryFormatter.

      Dmitri

      6 июня 2011 at 20:12

  2. А почему бы не прописывать для каждого свойства еще опционально typeof(someTypeconverter) — его и использовать при загрузке\выгрузке в строку…

    jocker1331

    10 июня 2011 at 14:02

    • Не знаю, а так можно? Я если честно с этим механизмом не знаком. Я правильно понимаю что свойство можно пометить правильным конвертером и это будет как если бы я реализовал ISerializable и конкретно для соответствующего поля использовал TypeConverter?

      Dmitri

      10 июня 2011 at 14:15


Оставить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: