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

0

В разд. 6.5 я приводил код компонента градиентной заливки GradientLabei. С помощью контекстного меню цвета начала и завершения заливки менялись местами. Код этого метода выглядел следующим образом:

PropertyDescriptor start = GetPropertyByName("StartColor"); PropertyDescriptor end = GetPropertyByName("EndColor"}; Color trop = (Color}start.GetValue(glabel}; start.SetValue(glabel, end.GetValue(glabel}); end.SetValue(glabel, tup);

Как видно из этого фрагмента, перестановка цветов состоит из трех шагов: цвет начала сохраняется в промежуточную переменную tmp, цвет начала заливки устанавливается равным цвету конца заливки и, наконец, цвет конца заливки устанавливается равным цвету начала заливки. С точки зрения компонента установка свойств состоит из двух частей: установка цвета начала заливки и затем установка цвета завершения. Выполнение этого кода в Visual Studio показывает, что среда разработки видит этот процесс точно так же. Действительно, меню Undo будет содержать две операции: отменив первую из них, мы получим компонент с одинаковыми цветами начала и завершения заливки, и только отменив второй, мы вернем компонент в предыдущее состояние. Но ведь с точки зрения пользователя это была одна операция! Более того, приведенный выше код достаточно прост, а ведь последовательность операций может,быть значительно длиннее. Проблема с откатом изменений не единственная. Если на одном из шагов произойдет ошибка, мы получим совершенно непредсказуемое и некорректное состояние компонента.

Транзакции (transaction) позволяют объединить несколько операций в один набор. Транзакция может быть либо выполнена целиком успешно, либо не выполнена вообще. Кроме того, редактор видит транзакцию как единую операцию и позволяет откатить только всю транзакцию полностью, что сохраняет компонент в непротиворечивом состоянии.

Транзакция создается с помощью метода createTransaction () класса

DesignerHost:

IDesignerHost host = (IDesignerHost) GetService(typeof(IDesignerHost)); DesignerTransaction trans = host.CreateTransaction();

Использование транзакции выглядит следующим образом:

using (trans} I

try

{

// Последовательность действий

// Подтверждаем транзакцию trans.Commit();

}

catch f

// Ошибка — откатываем транзакцию trans.Cancel();

}

}

Как вариант, можно создать именованную транзакцию, используя второй вариант конструктора:

DesignerTransaction trans = host.CreateTransaction{имя_транзакции) ;

Новый код метода Oninvertcoiors о показан в листинге 12.6. Теперь редактор увидит только одну операцию и, соответственно, откат изменений будет работать корректно.

Листинг 12 В Использование транзакции

private void О                    , _             .         _______

{

IDesignerHost host =

(IDesignerHost}glabel.Site.GetService(typeof(IDesignerHost)};

if (host = null) return;

DesignerTransaction trans =

host.CreateTransaction("Invert colors " + glabel.Name);

PropertyDescriptor start = GetPropertyByName("StartColor"); PropertyDescriptor end = GetPropertyByName("EndColor"};

// Меняем цвета местами using (trans}

f

try

{

Color tmp = (Color)start.GetValue(glabel); start.SetValue(glabel, end.GetValue(glabel}}; end.SetValue(glabel, tmp);

trans.Commit();

}

catch (

trans.Cancel();

}

}

1

Литература:

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

По теме:

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