Главная » C#, Компоненты » Стандартный набор значений-классов

0

С помощью класса ExpandabieObjectconverter можно реализовать очень интересное поведение редактора свойства. Рассмотрим некий компонент, который будет описывать запись об интервью (конечно, я мог бы придумать пример на основе класса GradientLabel, но, кажется, он уже порядком всем надоел):

public class InterviewControl : Component

{

, private InterviewRecord interviewRecord;

[Description("Запись об интервью")]

public InterviewRecord InterviewRecord {

get С

return interviewRecord;

}

set

{

interviewRecord = value;

}

]

}

Единственным свойством этого компонента будет запись об интервью (разумеется, я оставил только одно свойство в целях упрощения кода, в реальной задаче свойств у этого компонента будет очень много), представляемая абстрактным классом InterviewRecord:

public abstract class InterviewRecord

f

private string interviewer;

[Description("Кто проводит интервью")] public string Interviewer

}

get ( return interviewer; } set ( interviewer — value; }

}

}

Конкретные типы интервью будут описываться наследниками этого класса. Пока нам будет достаточно двух таких классов— телефонного интервью (класс Phone Interview) И ЛИЧНОЙ встречи (класс online Interview): public class Phonelnterview : InterviewRecord

private DateTime interviewDateTime; private string phoneNumber;

[Description("Номер телефона")3 public string PhoneNumber

get ( return phoneNumber; } set { phoneNumber = value; }

}

[DescriptionC^aTa и время интервью") 3 public DateTime InterviewDateTime

{

get ( return interviewDateTime; } set { interviewDateTime = value; }

}

}

public class Onlinelnterview : InterviewRecord

{

private DateTime interviewDate; private string address;

[DescriptionC’Anpec офиса") 3 public string Address

{

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

}

[Description("Дата интервью")] public DateTime InterviewDate

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

}

}

Разумеется, можно добавлять и другие типы, например, интервью через Интернет или по почте…

Добавив компонент на форму, мы увидим, что свойство недоступно для редактирования (рис. 8.9), т. к. редактор свойств просто не понимает, что делать

с нашим классом. Прямое использование конвертера ExpandabieObjectConverter в этом случае не спасает— ведь к свойству пока не привязан конкретный класс, поэтому нужно реализовать специальный класс конвертера.

Посмотрите, что это дает. Во-первых, наше свойство стало редактируемыми имеет три стандартных значения (рис. 8.10). Но самое интересное поведение нашего свойства проявляется при выборе значения, отличного от (None): набор вложенных свойств меняется в соответствии с типом выбранной записи, Для телефонного интервью появляется поле номера телефона и время (рис. 8. П), а для личной встречи — адрес и дата (рис. 8.12).

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

Еще один способ реализации такого поведения я опишу в разд. 9.3.4.

Листинг 8 15 Конвертор типа со стандартными значониями-классами

using System;

using System.Collections.Generic;

using System. Text;

using System.ComponentModel,-

namespace MyControl (

public class InterviewRecordConverter : ExpandableObjectConverter

[

/// <summary>

/// Разрешаем конвертировать из строки III </summary>

public override bool CanConvertFrom(

ITypeDescriptorContext context, Type sourceType)

{

if (sourceType =- typeof(string)) {

return true;

}

return base.CanConvertFrom(context, sourceType);

}

/// <summary>

/// Разрешаем конвертировать в строку III </summary>

public override bool CanConvertTo(

ITypeDescriptorContext context, Type destinationType}

{

if (destinationType —= typeof(string)) {

return true;

}

return base.CanConvertTo{context, destinationType};

/// <summary>

/// Конвертируем из строки в класс III </summary>

public override object ConvertFrom(

ITypeDescriptorContext context, System.Globalization.Culturelnfo culture, object value)

[

if (value is string) [

InterviewRecord interviewRecord = null;

switch ((string)value) {

case "Phonelnterview": [

interviewRecord – new Phonelnterview(); break;

}

case "Onlinelnterview":

[

interviewRecord — new Onlinelnterview[); break;

}

)

return interviewRecord;

}

return base.ConvertFrom(context, culture, value};

}

/// <summary>

/// Конвертируем в строку

/// </summary>

public override object ConvertTo(

ITypeDescriptorContext context,

System.Globalization.Culturelnfo culture,

object value, Type destinationType)

[

if (destinationType — typeof(string}) [

string convertedValue — "[None)";

if [value is Phonelnterview) [

convertedValue – "Phonelnterview";

}

else

if {value is Onlinelnterview) {

convertedValue = "Onlinelnterview";

}

return convertedValue;

}

return base.ConvertTo(

context, culture, value, destinationType);

}

/// <summary>

/// Есть набор стандартных значений III </suinmary>

public override bool GetStandardValuesSupported(

ITypeDescriptorContext context)

{

return true;

}

/// <summary>

/// Стандартный набор значений III </summary>

private readonly object{] _standardValues = new object{]{ null,

new Phonelnterview {}, new Onlinelnterview()

};

/// <summary>

/// Возвращаем стандартный набор значений III </summary>

public override TypeConverter.StandardValuesCollection

GetStandardValues{ITypeDescriptorContext context}

{

return

new TypeConverter.StandardValuesCollection(_standardValues);

}

/// <summary>

/// Запретить ввод других значений, кроме стандартных III </summary>

public override bool GetStandardValuesExclusive{ ITypeDescriptorContext context)

{

return true;

}

}

}

Литература:

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

По теме:

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