Skip to content

Пишем свое расширение для Редактора модели клиента СК-11

Статья-пример базовой реализации собственного расширения для клиента СК-11 для тех, кого ограничивает штатный функционал клиента СК-11.

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

Создание и настройка проекта в Visual Studio

  1. В VisualStudio создать новый проект типа "Библиотека классов (.NET Framework)"
  2. Указать платформу: ".NET Framework 4.8"

create_proj

  1. В настройках проекта указать Целевую платформу x64 для всех конфигураций сборки

build_options

  1. Для компиляции расширения необходимо подключить следующие библиотеки:

    Чтобы добавить ссылки на библиотеки нужно в дереве решения выбрать пункт Ссылки -> ПКМ -> Добавить ссылку...

links

  • из GAC нужно добавить сборки:

    • PresentationCore
    • PresentationFramework
  • из <ПАПКА УСТАНОВКИ VISUAL STUDIO>\Common7\IDE\Extensions\Microsoft\LiveShare\Agent\ или C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\ добавить сборку:

    • System.ComponentModel.Composition.dll
  • из папки с клиентом СК-11:

    • Monitel.Mal.dll
    • Monitel.UI.Infrastructure.dll

Результирующий вид дерева решения должен быть примерно такой:

links_result

Создание точки входа и объявление необходимых параметров для дальнейшего импорта в СК-11

Для подключения своего расширения к клиенту СК-11 необходимо выполнить ряд требований к ранее созданному классу:

  1. Класс должен реализовывать интерфейс IExtension (из пространства имен Monitel.UI.Infrastructure.Extensions)
  2. Описывать определенные значения метаданных для импорта в клиент СК-11

Выполнение требования 1:

class1_iextension

Выполнение требования 2:

class1_export

Итоговый код Class1.cs:

csharp
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Monitel.UI.Infrastructure.Services;
using Monitel.UI.Infrastructure.Extensions;
using System.ComponentModel.Composition;

namespace TestExtension
{
    [Export(typeof(IExtension))]
    [ExportMetadata("Name", "Тестовое расширение для СК-11")]
    [ExportMetadata("Description", "Расширение для Редактора модели СК-11")]
    [ExportMetadata("GroupName", "Расширения Вовк В.И.")]
    [ExportMetadata("ShowInToolBar", true)]
    [ExportMetadata("ShowInMenu", true)]
    [ExportMetadata("ExecutionMode", ExtensionExecutionMode.Control)]
    [ExportMetadata("SupportedModels", new string[] { "All" })]
    [ExportMetadata("MalUniversalAccess", true)]
    [ExportMetadata("LocaleId", "VovkVI.TestExtension")]
    public class Class1: IExtension
    {
        public BitmapSource Icon => null;
        public MenuItem MenuItem => null;
        public Control ToolBarItem => null;

        public Control CreateControl(IServiceManager services) 
        {
            return new TestControl(services);
        }

        public bool ShowDialog(Window owner, IServiceManager services)
        {
            return false;
        }
    }
}

где:

  • реализация IExtension:

    • Icon - определяет иконку расширения, которая будет отображена в выпадающем меню и на панели инструментов клиента СК-11
    • MenuItem - позволяет создать свое меню выпадающем меню клиента СК-11 (не просто кнопка, а, например, вложенные папки и т.д.)
    • ToolBarItem - позволяет создать свое меню на панели инструментов клиента СК-11
    • CreateControl - данный метод выполняется только если ExportMetadata("ExecutionMode", ...) имеет значение равное ExtensionExecutionMode.Control
    • ShowDialog - данный метод выполняется только если ExportMetadata("ExecutionMode", ...) имеет значение равное ExtensionExecutionMode.Dialog
  • значения атрибутов Export:

    • Name - Имя расширения. Отображается в выпадающем меню и на панели инструментов, если не задана иконка расширения;
    • Description - Описание расширения. Отображается при наведении курсора мыши на иконку расширения на панели инструментов;
    • GroupName - Произвольное значение. Предположительно участвует в какой-то внутренней логике СК-1;
    • ShowInToolBar - Определяет показывать ли расширение на панели инструментов;
    • ShowInMenu - Определяет показывать ли расширение в выпадающем меню;
    • ExecutionMode - Определяет режим работы расширения. Либо как встраеваемый элемент управления, либо как отдельное окно, если задано ExtensionExecutionMode.Dialog;
    • SupportedModels - Определяет с какими версиями канонической модели работать. Можно указать конкретную версию, например: CIM16;
    • MalUniversalAccess - ХЗ зачем, возможно дает особый вид доступа к объектной модели, но это не точно 😄
    • LocaleId - Произвольное значение. Какой-то идентификатор (расширения либо для определения локализации), нужен для внутренней логики СК-11.

Создание пользовательского элемента управления для отрисовки графического интерфейса

Для добавления графического интерфейса к расширению создадим компонент пользовательского элемента управления и назовем его как TestControl.xaml:

add_test_control

Добавим разметку. Расширение будет показывать сообщение с UIDом выбранного в дереве объекта

test_control_xaml

Итоговый код файла разметки TestControl.xaml:

xml
<UserControl x:Class="TestExtension.TestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TestExtension"
             mc:Ignorable="d" 
             Background="White"
             d:DesignHeight="300" d:DesignWidth="400">
    <StackPanel Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5">
        <TextBlock Text="Выберите объект в дереве и нажмите на кнопку для получения информации об объекте" TextWrapping="WrapWithOverflow" TextAlignment="Center"/>
        <Button x:Name="btnMsgInfo" Content="Информация об объекте" Height="32" Margin="10" Padding="5" FontSize="10"/>
    </StackPanel>
</UserControl>

Добавим логику. Для отображения заголовка расширения во вкладке нужно, чтобы класс TestControl реализовывал интерфейс IExtensionControl. ВАЖНО: чтобы конструктор класса TestControl принимал аргументом объект класса IServiceManager. Это нужно для доступа с ModelImage и другим сервисам редактора модели:

test_control_cs

Итоговый код файла TestControl.xaml.cs:

csharp
using System;
using System.Windows;
using System.Windows.Controls;
using Monitel.UI.Infrastructure.Services;
using Monitel.UI.Infrastructure.Extensions;

namespace TestExtension
{
    public partial class TestControl : UserControl, IExtensionControl
    {
        public string Header => "Тестовое расширение";
        public Control Toolbox => null;
        public bool CanClose() => true;
        public event EventHandler<EventArgs> HeaderChanged;

        public readonly IServiceManager _Services = null;

        public TestControl(IServiceManager services = null)
        {
            InitializeComponent();
            this._Services = services;
            this.btnMsgInfo.Click += btnClick;
        }

        private void btnClick(object sender, RoutedEventArgs e)
        {
            if (this._Services is null) return;
            var selObj = _Services.Navigation.SelectedObject;
            if (selObj is null) return;
            MessageBox.Show($"UID выбранного объекта: {selObj.Uid}", "Информация", MessageBoxButton.OK, MessageBoxImage.Information);
        }
    }
}

Сборка расширения

Собираем решение: "Сборка" → "Собрать решение" или Ctrl + Shift + B.

Подключение расширения к клиенту СК-11

connect

Для подключения расширения к клиенту СК-11 нужно:

  • Перейти в папку с клиентом СК-11, например:

    batch
    C:\Program Files\Monitel\CK-11\Client
  • Переместить в папку с клиентом СК-11 ранее собраный файл расширения TestExtension.dll

  • Создать *.xml файл с названием MNExtensions.Custom.xml название ОБЯЗАТЕЛЬНО должно быть именно таким.

    MNExtensions.Custom.xml

    xml
    <?xml version="1.0" encoding="utf-8" ?>
    <Extensions>
        <Extension FileName="TestExtension.dll" />
    </Extensions>
  • Всё, можно запускать редактор модели СК-11 😄

Результат работы расширения:

6

7

8

Разные полезности:

  • Чтобы получить доступ к объекту выбранному в дереве:
csharp
var selObj = services.Navigation.SelectedObject; // возвращает IMalObject
  • Чтобы получить доступ к объектной модели текущего контекста используем:
csharp
var MImage = services.DataSource.MainModelImage; // возвращает IModelImage
  • Чтобы получить доступ к объектной модели контекста AppData используем:
csharp
var ADImage = services.DataSource.AppDataModelImage; // возвращает IModelImage
  • Чтобы вывести сообщение в протокол используем:
csharp
services.Journal.WriteMessage(new JournalMessage(...));

Создано с VitePress