MyObject
Шаблон кастомного объекта
<MyObject Name="CustomControl" Type="CustomControl" Assembly="Template">
<!-- Элементы объекта -->
</MyObject>В атрибуте Type указывается имя класса, описывающего кастомный объект, а в качестве значения атрибута Assembly указывается имя сборки, в которой реализован этот класс.
Для удобства и разделения логики объекта, исходный код можно разбить на два класса:
CustomControlSettings - класс загрузки данных из xml-файла;
CustomControl - класс с бизнес-логикой.
Парсинг xml
Полный код шаблона класса CustomControlSettings:
using System.Xml;
namespace WorkflowForms.Controls
{
public class CustomControlSettings : ControlSettings
{
/*
* Набор свойств для хранения данных
* public string PropertyName { get; private set; }
*/
public CustomControlSettings(IDependable parent, XmlNode node, IWorkflowForm form, IDataBindingProvider dataBindingProvider)
: base(node, form)
{
/*
* Здесь должен быть парсинг xml-кода,
* чтобы получить значения тэгов и их атрибутов.
*/
}
}
}Конструктор класса принимает параметры:
parentIDependable - ссылка на экземпляр класса CustomCommand, для которого создавался объект типа CustomCommandSettings;formIWorkflowForm - форма, на которой описана кастомная команда;nodeXmlNode - узел, который соответствует тэгу <Command>, описанному в xml-файле формы.dataBindingProviderIDataBindingProvider -
Исполняемый код
Класс кастомного объекта наследуем от класса Control:
При наследовании класса Control необходимо реализовать свойства Value, Visible и Enabled. Кастомный объект не имеет значения, поэтому свойство Value возвращает null. Свойства Visible и Enabled возвращают false, так как объект не имеет графического интерфейса.
Get/Set-проперти
Для удобного взаимодействия с объектом и полного контроля за его работой следует реализовывать Get/Set-проперти, с помощью которых можно отдавать команды на проведение вычислений или взаимодействия со сторонними сервисами. Реализация get и set-проперти описывается в методах GetProperty и SetProperty соответственно.
Обращение к set-проперти происходит через команду ValueSetCommand:
В классе необходимо переопределить метод SetProperty:
В параметре parameters метода SetProperty хранится словарь всех параметров, описанных в команде ValueSetCommand в тэге <Parameters>.
Аналогичным образом отработает get-проперти:
В классе необходимо переопределить метод GetProperty:
В параметре parameters метода GetProperty хранится словарь всех параметров, описанных в тэге <Parameters> при обращении к get-проперти.
Элементы объекта
Константы и переменные
Для задания констант используем значения атрибутов, а для задания переменных - значения тэгов. В примере рассмотрим xml-код объекта с необязательным тэгом <Flag> и обязательным тэгом <Something>:
Парсинг xml
В конструкторе класса CustomControlSettings необходимо прописать код вида:
Так как тэг <Flag> является необязательным, то для получения его значения используется статический метод GetAttributeValue класса XmlParser. В третьем параметре (string path) указываем полный путь до тэга, значение атрибута которого нужно получить. Имя атрибута указывается в четвертом параметре (string attribute). Если тэг <Flag> или его атрибут Value будут отсутствовать в описании объекта, то свойству Flag будет присвоено значение по умолчанию, переданное пятым параметром (T defaultValue).
Для работы с переменным значением, указанным в тэге <Something>, используется механизм привязки данных, который позволяет в любой момент выполнения логики объекта получать актуальное значение объекта с именем MyVariable.
Для получения привязки к источнику данных в тэге <Something> используем статический метод GetRequiredElementDataBinding.
Исполняемая часть
В методе LoadSettings из объекта settings, переданного в метод в качестве параметра, можно получить нужные значения, обратившись к соответствующим публичным свойствам:
Если используется привязка данных, то на изменение привязанного объекта можно повесить Handler, который будет автоматически выполняться:
Где RecountChangeHandler представлен методом вида:
В рассматриваемом примере при изменении значения объекта с именем MyVariable, будет выполняться метод Recount.
При реализации бизнес-логики объекта работа с константными значениями простая:
А для получения значения из объекта типа IDataBinding необходимо использовать метод GetValue:
Полный список методов по ссылке.
Условие
В примере рассмотрим xml-код объекта с обязательным тэгом <AnyCondition> для передачи имени условия:
Парсинг xml
В конструкторе класса CustomControlSettings необходимо прописать код вида:
Так как имя условия указывается в качестве значения атрибута обязательного тэга, то для его получения используется статический метод GetRequiredAttributeValue класса XmlParser. В третьем параметре (string path) указываем полный путь до тэга, значение атрибута которого нужно получить. Имя атрибута указывается в четвертом параметре (string attribute). В данном случае используется константа NAME_ATTRIBUTE, описанная в базовом классе. Если элемент или его атрибут отсутствует, будет возвращено исключение типа InvalidXmlException.
Имея имя условия, объект типа ICondition можно получить через переменную form типа IWorkflowForm, используя метод GetCondition.
Исполняемая часть
В методе LoadSettings из объекта settings, переданного в метод в качестве параметра, можно получить объект типа ICondition, обратившись к публичному свойству AnyCondition:
При реализации бизнес-логики объекта можно получать значение условия, обращаясь к свойству Value:
Команды
В примере рассмотрим xml-код объекта с обязательным тэгом <AnyCommand> для передачи имени команды, которую должен вызвать объект:
Парсинг xml
В конструкторе класса CustomControlSettings необходимо прописать код вида:
Для получения имени команды используется статический метод GetRequiredAttributeValue класса XmlParser. В третьем параметре (string path) указываем полный путь до тэга, значение атрибута которого нужно получить. Имя атрибута указывается в четвертом параметре (string attribute). В данном случае используется константа NAME_ATTRIBUTE, описанная в базовом классе. Если элемент или его атрибут отсутствует, будет возвращено исключение типа InvalidXmlException.
Имея имя команды, объект типа ICommand можно получить через переменную form типа IWorkflowForm, используя метод GetCommand.
Исполняемая часть
В методе LoadSettings из объекта settings, переданного в метод в качестве параметра, можно получить объект типа ICommand, обратившись к публичному свойству AnyCommand:
В методе ExecuteAsyncCommand у объекта типа ICommand можно вызвать метод Execute, который запустит процесс выполнения команды:
В метод Execute можно передать словарь параметров, если команда использует входные параметры.
Получить результат выполнения команды:
Таблица
В примере рассмотрим xml-код объекта с обязательным тэгом <AnyCommand> для передачи имени команды, которую должен вызвать объект:
Парсинг xml
В конструкторе класса CustomControlSettings необходимо прописать код вида:
Исполняемая часть
В методе LoadSettings из объекта settings, переданного в метод в качестве параметра, можно получить объект типа DatabaseTable, обратившись к публичному свойству AnyDatabaseTable:
При реализации бизнес-логики у любого объекта можно вызывать метод GetProperty для обращения к get-проперти, реализованному у объекта. Например, можно обратиться к get-проперти Column у объекта DatabaseTable:
Первым аргументом идет имя get-проперти, а затем словарь параметров, которые принимает проперти объекта.
Так же можно вызывать метод SetProperty, чтобы обращаться к set-проперти объекта:
Логирование
Для добавления записей в журнал событий Windows используется класс Logger со статическим методом Write.
Пример добавления сообщения уровня Error в методе ExecuteAsyncCommand:
Обычно используются уровни событий: Error, Warning, Information.
Пример добавления сообщения уровня Information в конструкторе CustomCommandSettings при парсинге xml-кода команды:
Last updated