PDA

Просмотр полной версии : C# - как отобразить параметр из своего ВФБ на тренде?



Андрей_Б.
25.06.2019, 15:30
День добрый!
Написал на C# свой визуальный ФБ: отображает параметр, получаемый на входе.
Из контекстного меню на ВФБ вызываются его настройки и, планировался - график!
Не нашёл в документации, как на C# вызвать окно тренда и заставить его отображать параметр?
Как в этом случае тренд будет обращаться к архиву?
MasterSCADA 3.10

Единственное, что накопал:


using MasterSCADA.Trend;
//.......
TrendViews MyTrend;
//.......
MyTrend = new TrendViews(); // конструктор выполняется, но ничего не происходит.

ВФБ наследован от класса VisualControlBase.

SCADAMaster
25.06.2019, 15:50
Можно воспользоваться ControlContextMenuService.ShowTrend(IProjectHlp project, ITreePinHlp item, bool isTable, bool isJournal, IntPtr owner)
Для получения к нему доступа можно попробовать:
var ccms = project.Services.GetService(typeof(ControlContextM enuService)) as ControlContextMenuService;
ccms.ShowTrend(.....);


вот код этого метода внутри:
public void ShowTrend(IProjectHlp project, ITreePinHlp item, bool isTable, bool isJournal, IntPtr owner)
{
Type serviceType = ObjectFactoryService.Instance.GetType("MasterSCADA.Trend.Services.TrendService", false);
var fac = project.Services.GetService(serviceType) as ITrendService;
if (fac == null)
throw new InvalidOperationException("Нет доступа к сервису TrendService");


var param = new OpenTrendParameters
{
Item = item.GetParent(EParentType.ptFolder),
Parameters = new List<ITreePinHlp> {item},
Owner = owner,
AutoScroll = true,
DocType = EDocType.dtTrend,
Title = item.DisplayName
};
if (isTable)
param.View = "6F665323-E320-477B-94A3-440010AF0943";

if (isJournal)
{
param.DocType = EDocType.dtJournal;
param.View = "9E720E6A-5823-48B2-8EC3-DFC912E71761";
param.EventsEnabled = true;
param.EventFilters = new FilterCollection
{
new EventFilterData
{
SourceList = new List<string> {"#" + item.ID},
AlwaysIncludeCurrentObject = false,
Checked = true
}
};
}

var window = fac.Open(param);
if (window != null)
{
List<Window> list;
if (!_openedWindows.TryGetValue(owner, out list))
{
list = new List<Window>();
_openedWindows.Add(owner, list);
}
list.Add(window);
window.Closed += (sender, args) => list.Remove(window);
}
}

Андрей_Б.
25.06.2019, 18:07
Судя по определению "var" этот код должен исполняться непосредственно в блоке "C# Скрипт" МастерСКАДА.
Вообще-то я блок писал в Visual Studio, и не хотел бы дополнительные ФБ прикручивать...
ВФБ наследован от класса VisualControlBase.

Раз на то пошло, в каком пространстве имен находятся ControlContextMenuService и ControlContextM?

SCADAMaster
26.06.2019, 12:19
MasterSCADA.RT.Windows.ControlContextMenu

Андрей_Б.
23.11.2019, 03:19
Не нашёл компилятор:

(CS0234) Имя типа или пространства имен "Windows" отсутствует в пространстве имен "MasterSCADA.RT" (пропущена ссылка на сборку?)

MasterSCADA 3.10

SCADAMaster
23.11.2019, 09:39
Попробуйте у скрипта, на вкладке Настройки прописать ссылку на сборку:
MasterSCADA.RT.dll

Андрей_Б.
23.11.2019, 10:55
Помогло. Ругается дальше на строчку:

var ccms = project.Services.GetService(typeof(ControlContextM enuService)) as ControlContextMenuService;

Ругательства:

Строка 186 - Котельные.Контроль значений.hint.Скрипт : (CS1026) ожидалась )
Строка 186 - Котельные.Контроль значений.hint.Скрипт : (CS1002) ожидалась ;
Строка 186 - Котельные.Контроль значений.hint.Скрипт : (CS1525) Недопустимый терм ")" в выражении
Строка 186 - Котельные.Контроль значений.hint.Скрипт : (CS1002) ожидалась ;
Строка 186 - Котельные.Контроль значений.hint.Скрипт : (CS1525) Недопустимый терм ")" в выражении

Исправил так:

ControlContextM enuService;
var ccms = (ControlContextMenuService)HostFB.TreeItemHlp.Proj ect.Services.GetService(typeof(enuService));

Всё одно ругается:

Строка 190 - Котельные.Контроль значений.hint.Скрипт : (CS0246) Не удалось найти имя типа или пространства имен "ControlContextM" (пропущена директива using или ссылка на сборку?)
Строка 191 - Котельные.Контроль значений.hint.Скрипт : (CS0246) Не удалось найти имя типа или пространства имен "enuService" (пропущена директива using или ссылка на сборку?)

Типа ControlContextM в MasterSCADA.RT.Windows.ControlContextMenu видимо нет..

melky
23.11.2019, 11:07
насколько помню, using может применяться так же и при вызове внутри кода. Но не копал эту тему, просто видел в примерах такое.

Андрей_Б.
23.11.2019, 12:00
Ещё вопрос:

ControlContextMenuService.ShowTrend(IProjectHlp project, ITreePinHlp item, bool isTable, bool isJournal, IntPtr owner)

owner - это я так понимаю указатель на родительское окно.. Нужен, чтобы при закрытии родительского окна закрылся и тренд.. Это указатель тот же, что используется в WinAPI? Или какой-то свой? Как мне его заполучить?

SCADAMaster
23.11.2019, 17:40
Типа ControlContextM в MasterSCADA.RT.Windows.ControlContextMenu видимо нет..
Так вы using добавили?
MasterSCADA.RT.Windows.ControlContextMenu

Андрей_Б.
23.11.2019, 20:38
Да, добавил:
ссылку на сборку "MasterSCADA.RT.dll",
и в код добавил "using MasterSCADA.RT.Windows.ControlContextMenu;"


private void add_log<T>(string name, T x){
HostFB.TreeItemHlp.Project.ErrorTracer.ReportError (name+"="+x.ToString());
}
void Show_Trend(){
foreach (IDocumentHlp document in HostFB.TreeItemHlp.Project.Documents){
IAttributeHlp attribute = document.Attribute;
if (attribute.Opened){

var mnemoInfo = attribute.CurrentCallInfo;
var callType = mnemoInfo.CurrentCallType;
add_log("mnemoInfo",mnemoInfo);
add_log("callType",callType);

if (attribute.DocumentInfo.Handle != 0 && callType == MasterSCADA.Interfaces.ECallType.ctWindow ){

string path="Объект.Котельные.Значение параметра";
var item=HostFB.TreeItemHlp.Project.Item(path);
var ccms = (ControlContextMenuService)HostFB.TreeItemHlp.Proj ect.Services.GetService(typeof(ControlContextMenuS ervice));
ccms.ShowTrend(HostFB.TreeItemHlp.Project, (ITreePinHlp)item, true, false, (System.IntPtr)attribute.DocumentInfo.Handle );
return;
}
}
}
}


1. Всё компилируется, но непонятно, что подставить в качестве "IntPtr owner": выдаёт исключение "Выполнение Котельные.Скрипт | Адресат вызова создал исключение. : 0X80131604"

2. Как модифицировать строку "HostFB.TreeItemHlp.Project.ErrorTracer.ReportError (name+"="+x.ToString())", чтобы сообщения в лог попадали без статуса "ошибка"?

SCADAMaster
25.11.2019, 14:05
1. Всё компилируется, но непонятно, что подставить в качестве "IntPtr owner": выдаёт исключение "Выполнение Котельные.Скрипт | Адресат вызова создал исключение. : 0X80131604"



own = MasterSCADAHlp.Instance.MainWindowHandle;

Андрей_Б.
26.11.2019, 00:58
Походу, не светит мне ничего.. исключение и всё тут!

System.Reflection.TargetInvocationException: Адресат вызова создал исключение. ---> System.InvalidOperationException: Вызывающим потоком должен быть STA, поскольку этого требуют большинство компонентов UI.

в System.Windows.Input.InputManager..ctor()
в System.Windows.Input.InputManager.GetCurrentInputM anagerImpl()

Надо полагать, что это попытка вторгнуться в соседний поток

SCADAMaster
26.11.2019, 12:43
Судя по всему вы пытаетесь работать с трендом в скрипте или каком-то обработчике событий из рабочих потоков.
Тогда надо использовать BeginInvoke, но внимательно с этим быть, чтобы не переполнить очередь сообщений.
Про BeginInvoke было в блоге
https://insat.ru/blog/fb-skript-c-i-ego-ispolzovanie-v-masterscada-upravlenie-trendom/