Главная » C#, Компоненты » Определение режима разработки

0

У класса component есть одно важное свойство, про которое я обещал рассказать. Это свойство DesignMode. Оно возвращает true, если компонент находится в режиме разработки, и false, если компонент создан во время выполнения программы. Именно с помощью этого свойства можно отличить режим разработки от режима выполнения.

Такая проверка нужна очень часто. Например, если компонент имеет таймер вызывающий некоторые действия, то в режиме разработки этот таймер не должен работать (листинг 4.4).

Листинг 4.4.

pablic partial class MyComponent. : Component.

{

private System.Timers.Timer timer; public MyComponent () // Создаем таймер

timer = new System.Timers.Timer (); timer.Elapsed +=

new System.Timers.ElapsedEventHandler(timer Elapsed); timer.Enabled = true;

1

// Метод, вызываемый при срабатывании таймера void tirr,er_Elapsed(object sender, ElapsedEventArgs e) i

if (DesignMode) // Если это режим разработки — выходим return;

// Некоторые действия, которые будут выполнены только // в режиме выполнения (run-time)

}

}

Обращаю внимание на очень важный момент. Нельзя использовать свойство DesignMode в конструкторе компонента или любом другом методе, вызываемом из конструктора, например, так:

public partial class MyComponent : Component i

private System.Timers.Timer timer;

public MyComponent ()

[

if (DesignMode) // Неверно — нельзя использовать // эту проверку в конструкторе

{

timer = new System.Timers.Timer(); timer.Elapsed +=

new System.Timers.ElapsedEventHandler(timer Elapsed;;

timer.Enabled true;

}

}

}

Это связано с тем, что сначала вызывается конструктор компонента, а уже затем компонент привязывается к контейнеру и создается интерфейс i.site. Другими словами, во время выполнения конструктора компонент еще не может определить режим работы и DesignMode всегда вернет false. Не откладывая в долгий ящик, сразу расскажу, как быть в таких случаях. Вариантов определения режима разработки довольно много, но у каждого способа есть свои ограничения и недостатки. Можно, например, проверять имя процесса:

public new bool DesignMode

{

get i

return (System.Diagnosti cs.Process.

GetCurrentProcess () .ProcessName -= "doveriv"} ;

}

Но этот способ не будет работать в среде Mono, Borland Delphi .NET или других редакторах, отличных от Visual Studio. Можно использовать проверку режима работы менеджера лицензий:

public new bool DesignMode I

get

!

return System.ComponentModei.Li ccnseManager. UsageMode System.ComponentModei.LxcenseUsageMode.Designtime;

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

private bool I5DesignMode()

if{Site 1- null )

return Site.DesignMode;

StackTrace stackTrace = new StackTrace (); inr frameCount = stackTrace.FrameCount – 1;

for( int frame = 0; frame < frameCount; frame++ ) (

Type type = stackTrace.GetFrame(frame).GetMethod().DeclaringType; if (typeof(IDesignerHost) .IsAssignableFrom(type)) return true;

}

return false;

}

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

Мне кажется, что наиболее корректный выход в такой ситуации— постараться вынести создание объектов из конструктора, использовав, например, интерфейс isupportinitialize. Этот интерфейс имеет всего два метода:

public interface ISupportlnitialize {

void Beginlnit () ; void Endlnit () ;

]

МетодBegmin:t () вызывается в начале инициализации компонентов, а метод Endimt()— при завершении инициализации. В коде формы это выглядит следующим образом:

! (System. ComponentMode 1.1 Support Initialize)

(this. MyComponent)).Beginlnit(); … инициализация компонентов … ((System. ComponentModel. I Support Initialize)

(this. MyComponent)).Endlnit();

Так как метод Endlnit о вызывается после конструкторов, то в нем проверять флаг DesignMode вполне допустимо (листинг 4.5). Способы, перечисленные выше, стоит применять, если вынести создание объектов из конструктора не получается никаким образом.

Кстати, в .NET 3.5, при использовании библиотеки WPF. определить режим разработки можно более простым способом:

if (Systarn.ComponentModel. DesignerPrcperties . GetlslnDes: gnMode (th is) ) I

11 Это режим разработки

}

Но без WPF придется работать "по старинке".

Лисшш 4 5 Создании ооьскшп только и рижимс пыполнсним

public class MyComponent : ISupportlnitialize {

private Timer timer;

public void BeginlnitO {

}

public void Endlnit() I

if (!DesignMode) // Здесь проверять можно {

timer = new Timer();

timer.Tick += new EventHandler {timer__Tick}; timer.Interval = 500; timer.Enabled = true;

}

}

}

Литература:

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

По теме:

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