Friday, September 2, 2011

Быстрое сохранение в XML класса Font, Color, enum...

Вот лень мне было по кусочкам Font сохранять в XML. Нашел вот такой способ:

public static XmlElement AddElementByConverter<T>(XmlElement parentNode, string nodeName, T attrValue)
{
  TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
  string value = converter.ConvertToString(attrValue));
  .... ну и тут дальше как обычно
}


И загружать просто:

public static T ReadByConverter<T>(XmlNode element, string path, T defaultValue)
{
   T nodeValue = defaultValue;
   XmlNode node = element.SelectSingleNode(path);

   .........
   TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
   nodeValue = (T) converter.ConvertFromString(valueString);
   if (nodeValue == null)
      nodeValue = defaultValue;
   .........
   return nodeValue;
}


Такая конструкция замечательно глотает и Font и Color и любой enum.
Типа кодюлька номер раз :)

Название

Подумал, если короткие фразы, это "коротюльки", то короткие кусочки кода должны бы называться "кодюльки". Может книгу надо было назвать не Сборник рецептов, а Сборник кодюлек. Ну или как-то так... :)

Thursday, September 1, 2011

Интересная штука с загрузкой изображений

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

Сохраняю:

using (MemoryStream ms = new MemoryStream())
{
 this.bitmap.Save(ms, ImageFormat.Bmp); 
 byte[] bitmapData = ms.ToArray(); 
 string imgBase64 = Convert.ToBase64String(bitmapData);
 xmlImage.InnerText = imgBase64;
}


Загружаю:

string imgBase64 = xmlImage.InnerText;
if (!string.IsNullOrEmpty(imgBase64)) 
  byte[] bitmapData = Convert.FromBase64String(imgBase64); 
using (MemoryStream ms = new MemoryStream(bitmapData))   
  this.bitmap = Image.FromStream(ms) as Bitmap
;

Все работает без проблем - bitmap отображается как нужно, размеры сохранены
и вообще все отлично.

Но если попытаться сохранить этот загруженный image еще раз,
то получаю ошибку:
        A generic error occurred in GDI+.
Что сие значит не понятно.

Решил проблему просто, но не понятно - либо не закрывать поток,
либо создавать новый image, соответственно с новым потоком.

Т.е. либо так:

  MemoryStream ms = new MemoryStream(bitmapData); 
  this.bitmap = Image.FromStream(ms) as Bitmap;
   

Либо так:

  this.bitmap = new Bitmap(Image.FromStream(ms) as Bitmap);

Первый вариант мне не нравится, прямо душу режет.
Второй еще пережить можно, хотя не понятно почему и в чем проблема.

UPD: Т.е. получается что при выполнении FromStream используется тот же буфер, что
я создавал в потоке.

UPD: Интересно этот редактор параграфы переставляет. Вроде сохраняешь
нормально, а получается такая каша... Хоть бы пофиксили. Задолбало.