Добавление и удаление перьев

<< Click to Display Table of Contents >>

Navigation:  Проект > Элементы дерева объектов > Палитра ФБ > Служебные > Скрипт > Руководство и примеры > Работа с трендами >

Добавление и удаление перьев

Добавление и удаление перьев можно выполнять перетаскиванием мышью или используя окно добавления перьев. В ряде случае может потребоваться добавление перьев по определенному алгоритму, которое можно сделать с помощью скрипта.

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

sluzhebnie_skript_rukovodstvo_i_primery_rabota_s_trendami_dobavlenie_i_udalenie_perev1

Перейдем к скрипту. Создадим две заготовки кода, для обработки фронта на входе Добавить и Удалить.

bool? M = false;
bool? L = false;
public override void Execute()
{
 if (Добавить == true && M == false)
 {
 }
 M = Добавить;
 if (Удалить == true && L == false)
 {
 }
 L = Удалить;
}

Получить тренд можно точно также как и в прошлых примерах.

Получить коллекцию перьев уже добавленных на тренд можно используя метод:

var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.Graph2D>().ToList();

list будет представлять собой коллекцию, которую можно перебрать в цикле.

Для того чтобы добавить перья в тренд нужно

trend.AddParametr(ITreePinHlp Pin);

Чтобы данный метод был доступен, нужно добавить пространство имен:

using MasterSCADA.Trend.Helpers;

Для удаления, нужно найти нужное перо в коллекции (например по имени, или по привязке к определенной переменной) и вызвать метод:

trend.DeleteParameter(pen);

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

https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/delegates/

Сначала напишем методы для добавления и удаления. В качестве аргументов, мы будем передавать в них наш класс тренда, и коллекцию List с именами наших перьев, которые нужно удалить или добавить.

Метод добавления перьев будет выглядеть так:

private void AddPen(Trend trend, List<string> Names)
{
    var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.Graph2D>().ToList();
    foreach (string name in Names)
    {
        if (list.FindIndex(x => x.Name == name) >= 0) continue; //переменая есть добавлять нельзя
        var pin = (ITreePinHlp)HostFB.TreeItemHlp.Parent.GetChild(name); //находим переменную в дереве объектов
        if (pin == null) continue; //переменной нет - проходим дальше
        trend.AddParametr(pin); //добавляем в тренд
    }
}

В нем мы сначала получаем коллекцию перьев, затем перебираем эту коллекцию в цикле foreach. С помощью поиска FindIndex мы ищем перо с таким именем, если перо уже добавлено - то пропускаем это имя, поскольку такое перо уже добавлено. А если же такого пера нет, то находим переменную по данному имени, как мы делали ранее, и если такая переменная есть - добавляем ее в тренд.

Метод удаления перьев будет выглядеть так:

private void DeletePen(Trend trend, List<string> Names)
{
    var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.Graph2D>().ToList();
    foreach (string name in Names)
    {
        var pen = list.Find(x => x.Name == name); //находим перо
        if (pen != null) trend.DeleteParameter(pen); //если нашли - удаляем
    }
}

Теперь сделаем делегат для данных функций. Для этого в теле класса объявим его:

delegate void Operation(Trend trend, List<string> Names);

Обратите внимание что метод имеет аналогичную сигнатуру, как и методы DeletePen и AddPen - не возвращает значение (void), и имеет два входных аргумента Trend и List<string>.

Теперь создадим метод для обращения к тренду и в него передадим наш делегат и коллекцию имен.

private void ChangeTrend(Operation Oper, List<string> Collect)
{
 //Ссылка на текущий проект       
 var Project = HostFB.TreeItemHlp.Project;
 //получаем корневой объект
 var ParentObject = (ITreeItemHlp)HostFB.TreeItemHlp.Parent;
 //получаем тренд     
 RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate
 {
  foreach (var trend in Project.GetService<TrendService>().Opened)
  {
   var host = trend.Host as System.Windows.Forms.Control;
   if (host != null)
   {
    Object name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME);
    if (name.ToString() != ИМЯ_ТРЕНДА || trend.Attribute.TreeItem.ID != ParentObject.ID || trend.Attribute.DisplayName != ИМЯ_ОКНА) continue;
    Oper(trend, Collect); //вызов метода
    break;
   }
  }
 }));
}

Код внутри метода нам уже знаком. Новая по сути одна строчка:

Oper(trend,Collect); //вызов метода

Здесь вызывается метод, который мы получили как аргумент.

Осталось только добавить вызов метода ChangeTrend в метод Execute.

public override void Execute()
{
 if (Добавить == true && M == false)
 {
  ChangeTrend(AddPen, Collect);
 }
 M = Добавить;
 if (Удалить == true && L == false)
 {
  ChangeTrend(DeletePen, Collect);
 }
 L = Удалить;
}

 

Все что нужно сделать - передать вместо первого аргумента нужный нам метод, добавления или удаления пера.

Итоговый код будет выглядеть так:

public partial class ФБ : ScriptBase
{
    const string ИМЯ_ТРЕНДА = "Тренд";
    const string ИМЯ_ОКНА = "Мнемосхема";
    bool? M = false;
    bool? L = false;
    delegate void Operation(Trend trend, List<string> Names);
    List<string> Collect = new List<string>() { "Параметр 1", "Параметр 2" };
    public override void Execute()
    {
        if (Добавить == true && M == false)
        {
            ChangeTrend(AddPen, Collect);
        }
        M = Добавить;
        if (Удалить == true && L == false)
        {
            ChangeTrend(DeletePen, Collect);
        }
        L = Удалить;
    }
    private void ChangeTrend(Operation Oper, List<string> Collect)
    {
        //Ссылка на текущий проект       
        var Project = HostFB.TreeItemHlp.Project;
        //получаем корневой объект
        var ParentObject = (ITreeItemHlp)HostFB.TreeItemHlp.Parent;
        //получаем тренд     
        RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate
        {
            foreach (var trend in Project.GetService<TrendService>().Opened)
            {
                var host = trend.Host as System.Windows.Forms.Control;
                if (host != null)
                {
                    Object name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME);
                    if (name.ToString() != ИМЯ_ТРЕНДА || trend.Attribute.TreeItem.ID != ParentObject.ID || trend.Attribute.DisplayName != ИМЯ_ОКНА) continue;
                    Oper(trend, Collect); //вызов метода
                    break;
                }
            }
        }));
    }
    private void AddPen(Trend trend, List<string> Names)
    {
        var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.Graph2D>().ToList();
        foreach (string name in Names)
        {
            if (list.FindIndex(x => x.Name == name) >= 0) continue; //переменая есть добавлять нельзя
            var pin = (ITreePinHlp)HostFB.TreeItemHlp.Parent.GetChild(name); //находим переменную в дереве объектов
            if (pin == null) continue; //переменной нет - проходим дальше
            trend.AddParametr(pin); //добавляем в тренд
        }
    }
    private void DeletePen(Trend trend, List<string> Names)
    {
        var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.Graph2D>().ToList();
        foreach (string name in Names)
        {
            var pen = list.Find(x => x.Name == name); //находим перо
            if (pen != null) trend.DeleteParameter(pen); //если нашли - удаляем
        }
    }
}

 

Проверим работу нашего скрипта.

sluzhebnie_skript_rukovodstvo_i_primery_rabota_s_trendami_dobavlenie_i_udalenie_perev

Переменные добавляются и удаляются.

Готовый пример можно скачать по ссылке.