Главная » C#, Компоненты » Управление сериализацией

0

В предыдущем разделе я рассказывал, как среда осуществляет процесс сериализации. В частности о том, что при сериализации просматриваются все публичные свойства. Каждое из них анализируется на необходимость сериализации.

Указать необходимость сериализации можно с помощью атрибута

DesignerSerializationVisibility.’

О DesignerSerializationVisibility.Hidden—запретить СериализацНЮ свойства;

?     DesignerSerializationVisibility. Visible— разрешить СериализациЮ свойства;

?     DesignerSerializationVisibility. Content— Сериализовать СВОЙСТВО "по содержанию".

Зачем нужно запрещать сериализацию свойства? С несколькими случаями мы уже сталкивались. В разд. 6.7 мы скрывали от сериализации виртуальные свойства, т. е. свойства, которые существуют только в режиме разработки. При исправлении проблемы в стандартном наборе значений (см. разд. 8.5) пришлось дублировать свойство Gradient Prop, а чтобы одно и то же свойство не сохранялось два раза, одно из них мы скрывали. Таким образом, можно сформулировать две причины, по которым нужно скрывать свойство от сериал изации:

?     свойство не существует в режиме выполнения;

?     значение свойства сохраняется каким-то другим образом.

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

Еще один случай— дублирование одного из свойств "внутреннего" компонента:

[DesignerSerializationVisibility(

DesignerSerializationVisibility-Hidden)]

public DateTime DateValue

get{ return pTextBox.DateValue; } set{ pTextBox.DateValue = value; }

}

Возможен вариант, когда в сохранении свойства нет смысла, т. к. оно изменяется только в режиме выполнения:

[Browsable(false)] [DesignerSerializationVisibility{

DesignerSerializationVisibility.Hidden)] public bool IsModified

{

get[ return pTextBox.Modified; ) set{ pTextBox.Modified = value; }

}

Но такие свойства нет смысла выносить в редактор свойств, и поэтому у него присутствует еще атрибут Browsable (false}.

Лис1инг 10 3 Компонент, имеющим дублированные свойства

using System;

using System.ComponentModel; using Syston.ComponentModel.Design; using System.Drawing; using System.Windows.Forms;

using System.ComponentModel.Design.Serialization;

namespace ContentSerializationExample

{

11 Класс для демонстрации использования // атрибута DesignerSerializationVisibility

public class ContentSerializationControl : UserControl {

[DesignerSerializationVisibility(

DesignerSerializationVisibility.Hidden)] public DimensionData Dimensions

{

get

{

return new DimensionData(this);

}

}

}

// Этот атрибут говорит, что свойства этого класса // будут показываться в Редакторе свойств как отдельные поля [TypeConverterAttribute(typeof(ExpandableObjectConverter))] public class DimensionData

{

// Сохраняем владельца свойств private Control owner;

// Конструктор

internal DimensionData(Control owner)

{

this.owner = owner;

}

// Свойство OwnerLocation берет значение у объекта owner

public Point OwnerLocation [

get [

return owner.Location;

}

set

{

owner.Location = value;

// Свойство OwnerSize берет значение у объекта owner public Size OwnerSize (

get (

return owner.Size;

}

set

{

owner.Size — value;

}

)

}

)

Атрибут DesignerSerializationVisibility.Content указывает, ЧТО сериализа- ция будет производиться с помощью сохранения содержимого объекта. Например, если это набор строк, как, например, в листинге 10.4, то соответствующий код будет представлять собой инициализацию строкового массива:

this.serializationDemoControll.Strings —

new string[j { "aa", "bb", "cc"};

Обратите внимание на инициализацию свойства в конструкторе:

this.Strings = new string[0];

Если этого не сделать или инициализировать не свойство, а только поле stringsvaiue, то при пустом наборе строк иногда возникает ошибка (рис. 10.2).

Для типа string [] разницы между атрибутами visible и content не видно, а вот тип StringCoilection показывает ее более наглядно. Сравните листинги 10.5 и 10.6. Я специально выделил полужирным шрифтом отличающийся код. Первый листинг сохраняет коллекцию в "режиме" visible. Результат будет таким:

ComponentResourceManager resources =

new ComponentResourceManager{typeof(Forml)); this.serializationDemoControll.StringCoilection = ( (StringCoilection) (resources.GetObject{

"serializationDemoControll.StringCoilection")));

Во втором случае используется атрибут content и результат будет таким:

this.serializationDemoControll.StringCoilection.AddRange( new string!] { "aaa", "bbb"});

Как видно из результата сериализации, атрибут visible создает новый объект (вызывая метод Getobjecto), а атрибут Content подразумевает, что объект уже существует. При попытке сериализовать неинициализированный объект Visual Studio выдаст ошибку (рис. 10.3).

Листинг 10 4 Сериализации "по содержимому ‘

using System;

using System.ComponentModel; using System.ComponentModel.Design; using System.Drawing; using System.Windows.Forms;

using System.ComponentModel.Design.Serialization; using System.Text;

namespace ContentSerializationExample

{

public class SerializationDemoControl : UserControl

t

private String[] stringsValue;

public SerializationDemoControl{)

{

this.Strings = new string[0];

}

[DesignerSerializationVisibility(

DesignerSerializationVisibility.Content)] [DefaultValue(new String[0]))

public String[] Strings

{

get {

return this.stringsValue;

}

set [

if (value != null)

{

this.stringsValue « value;

else

{

this.stringsValue = new string[0];

1

}

}

}

}

Листинг 10 5 Сериализация st-r.rwCo. I«-_tio.i с атрибутом Vi^olc

using System;

using System.ComponentMode1; using System.ComponentModel.Design; using System.Drawing; using System.Windows.Forms;

using System.ComponentModel.Design.Serialization; using System.Text;

using System.Collections.Specialized;

namespace ContentSerializationExample {

public class SerializationDemoControl : UserControl {

private StringCollection stringCollection = null;

[DesignerSerializationVisibility(

DesignerSerializationVisibility.Visible)1 [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]

public StringCollection StringCollection {

get { return stringCollection; } set { stringCollection = value; }

}

У

}

Листинг 10 6 Сериализация Stx.ingCollectj.on с атрибутом Cortent

using System;

using System.ComponentModel;

using System.ComponentModel.Design;

using System. Drawing;

using System.Windows.Forms;

using System.ComponentModel.Design.Serialization; using System.Text;

using System.Collections.Specialized;

namespace ContentSerializationExample

}

public class SerializationDemoControl : UserControl {

private StringCollection stringCollection = new StringCollection();

[DesignerSerializationVisibility(

DesignerSerializationVisibility. Visible)] [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")]

public StringCollection StringCollection {

get { return stringCollection; } set { stringCollection = value; }

}

Рис. 10.2. Ошибка при сериализации неинициализированного свойства

Рис. 10.3. Ошибка при попытки сериализации неинициализированного свойства в режиме Content

}

Литература:

Агуров П. В. C#. Разработка компонентов в MS Visual Studio 2005/2008. – СПб.: БХВ-Петербург, 2008. — 480 е.: ил.

По теме:

  • Комментарии