Когда изучал создание дополнений к Aveva на языке C# сделал небольшую формочку, показывающую краткую информацию о дочерних элементах текущего элемента. Никакой особой смысловой нагрузки она не несёт, но возможно кому-то поможет разрабатывать свои дополнения.
В работе выглядит следующим образом:
Главный класс, подгружающий дополнение в Aveva
#region Using
using System;
using Aveva.ApplicationFramework;
using Aveva.ApplicationFramework.Presentation;
#endregion
class Main : IAddin
{
///<summary>
/// Вызывается при запуске
///</summary>
public void Start(ServiceManager servMan)
{
CommandManager commMan = CommandManager.Instance;
commMan.Commands.Add(new MemberListCommand());
}
///<summary>
/// Вызывается при закрытии
///</summary>
public void Stop() { }
///<summary>
/// Описание
///</summary>
public string Description { get { return "AvevaMemberListWindowAddin ( добавляет окно списка дочерних элементов )"; } }
///<summary>
/// Заголовок
///</summary>
public string Name { get { return "AvevaMemberListWindowAddin"; } }
}
Дополнительный класс, хранящий необходимую информацию об элементе
using System;
///<summary>
/// Элемент таблицы
///</summary>
public class MemberListItem
{
private string type;
private string spRef;
private string description;
private double weight;
private double count;
///<summary>
/// Конструктор
///</summary>
///<param name="type">Тип</param>
///<param name="spRef">Название стандарта</param>
///<param name="weight">Вес одной единицы</param>
///<param name="count">Количество</param>
///<param name="description">Детальное описание</param>
public MemberListItem(string type, string spRef, double weight, double count, string description)
{
this.type = type;
this.spRef = spRef;
this.weight = weight;
this.count = count;
this.description = description;
}
///<summary>
/// Сложение двух одинаковых элементов
///</summary>
///<param name="item">Элемент для сложения</param>
///<returns>True в случае удачного сложения элементов</returns>
public bool AddItem(MemberListItem item)
{
if (!item.Type.Equals(this.type) ||
!item.SpRef.Equals(this.spRef) ||
!item.Weight.Equals(this.weight))
return false;
this.count += item.Count;
return true;
}
///<summary>
/// Тип
///</summary>
public string Type
{
get { return this.type; }
set { this.type = value; }
}
///<summary>
/// Название стандарта
///</summary>
public string SpRef
{
get { return this.spRef; }
set { this.spRef = value; }
}
///<summary>
/// Вес 1 единицы
///</summary>
public double Weight
{
get { return this.weight; }
set { this.weight = value; }
}
///<summary>
/// Количество
///</summary>
public double Count
{
get { return this.count; }
set { this.count = value; }
}
///<summary>
/// Суммарный вес (округлено до 3го знака)
///</summary>
public double WeightSum
{
get { return Math.Round(this.count * this.weight, 3); }
}
///<summary>
/// Детальное описание
///</summary>
public string Description
{
get { return this.description; }
set { this.description = value; }
}
///<summary>
/// Вовзращает свойства элемента в виде массива
///</summary>
public string[] ToArray()
{
return new string[] { this.Type, this.SpRef, this.Weight.ToString(), this.Count.ToString(), this.WeightSum.ToString(), this.Description };
}
}
Рабочий класс, составляющий список элементов
#region Using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Aveva.ApplicationFramework;
using Aveva.ApplicationFramework.Presentation;
using Aveva.Pdms.Database;
using Aveva.PDMS.Database.Filters;
using Aveva.Pdms.Geometry;
using Aveva.Pdms.Shared;
using Aveva.Pdms.Utilities;
#endregion
///<summary>
/// Показать/скрыть список дочерних элементов
///</summary>
public class MemberListCommand : Command
{
#region Свойства
private WindowManager winMan;
private DockedWindow window;
private MemberList form;
#endregion
#region Конструктор
public MemberListCommand()
{
this.winMan = Aveva.ApplicationFramework.Presentation.WindowManager.Instance;
this.Key = "AvevaMemberListWindowAddin.ShowOrHideWindow";
this.Description = "Список дочерних элементов";
// создаём окно
this.form = new MemberList();
this.window = this.winMan.CreateDockedWindow("MemberListWindow", "Список дочерних элементов", this.form, DockedPosition.Floating);
this.window.Title = "Список дочерних элементов";
this.window.Tooltip = "Показывает сводку по дочерним элементам для текущего элемента";
this.window.SaveLayout = true;
// подписываемся на события
this.winMan.WindowLayoutLoaded += this.OnWindowLayoutLoaded; // открытие окна
this.window.Closed += this.OnWindowClosed; // закрытие окна
CurrentElement.CurrentElementChanged += this.OnCurrentElementChanged; // изменение ce
}
#endregion
#region Методы
///<summary>
/// Обновить список элементов
///</summary>
private void Update()
{
this.form.Clear();
this.form.AddItems(this.GetElements(CurrentElement.Element).OrderBy(x => x.Type).ThenBy(x => x.SpRef).ToList());
}
///<summary>
/// Сбор дочерних элементов
///</summary>
///<param name="elem">Элемент</param>
private List<MemberListItem> GetElements(DbElement elem)
{
List<MemberListItem> result = new List<MemberListItem>();
DBElementCollection elems = new DBElementCollection(elem);
foreach (DbElement dbEle in elems)
{
string type = dbEle.GetAsString(DbAttributeInstance.FULL);
string spRefName = string.Empty;
double weight = 0;
double count = 0;
string description = string.Empty;
if (dbEle.IsAttributeValid(DbAttributeInstance.SPRE))
{
DbElement spRefEle = dbEle.GetElement(DbAttributeInstance.SPRE);
if (spRefEle.IsValid)
{
spRefName = spRefEle.GetAsString(DbAttributeInstance.NAME);
if (spRefEle.IsAttributeValid(DbAttributeInstance.CMPR))
{
DbElement cmpRefEle = spRefEle.GetElement(DbAttributeInstance.CMPR);
if (cmpRefEle.IsValid)
{
if (type.Equals(DbElementTypeInstance.TUBING.Name) || type.Equals(DbElementTypeInstance.BEND.Name))
{
if (cmpRefEle.IsAttributeValid(DbAttributeInstance.UWEI))
Double.TryParse(cmpRefEle.GetAsString(DbAttributeInstance.UWEI)
.Replace('.', ',').Replace('(', ' ').Replace(')', ' ').Trim(), out weight);
else
Double.TryParse(cmpRefEle.GetAsString(DbAttributeInstance.CWEI)
.Replace('.', ',').Replace('(', ' ').Replace(')', ' ').Trim(), out weight);
}
else
{
if (cmpRefEle.IsAttributeValid(DbAttributeInstance.CWEI))
Double.TryParse(cmpRefEle.GetAsString(DbAttributeInstance.CWEI)
.Replace('.', ',').Replace('(', ' ').Replace(')', ' ').Trim(), out weight);
else
Double.TryParse(cmpRefEle.GetAsString(DbAttributeInstance.UWEI)
.Replace('.', ',').Replace('(', ' ').Replace(')', ' ').Trim(), out weight);
}
}
}
DbElement detRefEle = spRefEle.GetElement(DbAttributeInstance.DETR);
if (detRefEle.IsValid)
description = detRefEle.GetAsString(DbAttributeInstance.RTEX);
}
}
// трубы и изгибы считаются отдельно в мм
if (type.Equals(DbElementTypeInstance.TUBING.Name))
Double.TryParse(dbEle.GetAsString(DbAttributeInstance.ITLE).Replace("mm", string.Empty).Replace('.', ','), out count);
else if (type.Equals(DbElementTypeInstance.BEND.Name))
Double.TryParse(dbEle.GetAsString(DbAttributeInstance.FITLEN).Replace("mm", string.Empty).Replace('.', ','), out count);
else
count = 1;
// если такой элемент в коллекции уже есть, приплюсуем к нему, иначе добавляем новый элемент
if (result.Exists(x => x.Type == type && x.SpRef == spRefName))
{
MemberListItem foundItem = result.Find(x => x.Type == type && x.SpRef == spRefName);
foundItem.Count += count;
}
else
result.Add(new MemberListItem(type, spRefName, weight, count, description));
}
return result;
}
#endregion
#region Command
///<summary>
/// Вызов команды
///</summary>
public override void Execute()
{
if (this.Checked)
{
this.window.Show();
if (!this.window.Visible)
return;
this.Update();
this.Checked = false;
}
else
{
this.window.Hide();
this.Checked = true;
}
}
#endregion
#region События
///<summary>
/// При изменении CE
///</summary>
public void OnCurrentElementChanged(object sender, CurrentElementChangedEventArgs e)
{
if (!this.window.Visible)
return;
this.Update();
}
///<summary>
/// При открытии окна
///</summary>
private void OnWindowLayoutLoaded(object sender, EventArgs e)
{
this.Checked = true;
}
///<summary>
/// При закрытии окна
///</summary>
private void OnWindowClosed(object sender, EventArgs e)
{
this.Checked = true;
}
#endregion
}
Чтобы подключить дополнение надо:
1. В файл OutfittingAddin.xml добавить строку:
<string>AvevaMemberListWindowAddin</string>
2. Скопировать файл AvevaMemberListWindowAddin.dll в папку, куда установлена Aveva
3. Создать кнопку на панели задач и указать ей в качестве команды
AvevaMemberListWindowAddin.ShowOrHideWindow
Во вложении находодится скомпилированная DLL'ка и проект.