After doing a lot of digging I discovered iX 2.20 no longer creates tags as properties. They are now created as fields (public variables). This seems to have been to reduce baggage created by defining tags as properties. I also found iX has two types of tags it can create: GlobalDataItem and LightweightTag. Although these classes are similar, they cannot be recast to the other type. To deal with this, I created a generic StringToTag function
In the Tags script, add the following static function
Code: Select all
public static T StringToTag<T>(string tagName) where T : class
{
Type type = typeof(T);
FieldInfo[] props = Globals.Tags.GetType().GetFields();
foreach (FieldInfo prop in props) {
if (prop.FieldType.Equals(type)) {
if (prop.Name.Equals(tagName, StringComparison.CurrentCultureIgnoreCase)) {
return (T)prop.GetValue(Globals.Tags);
}
}
}
return null;
}
Do not forget to add "using System.Reflection;" to head of Tags script.
As an example of how to use the function, I created a sample screen named Screen1 with a single button, script for screen shown below
Code: Select all
//--------------------------------------------------------------
// Press F1 to get help about using script.
// To access an object that is not located in the current class, start the call with Globals.
// When using events and timers be cautious not to generate memoryleaks,
// please see the help for more information.
//---------------------------------------------------------------
namespace Neo.ApplicationFramework.Generated
{
using System.Windows.Forms;
using System;
using System.Drawing;
using Neo.ApplicationFramework.Tools;
using Neo.ApplicationFramework.Common.Graphics.Logic;
using Neo.ApplicationFramework.Controls;
using Neo.ApplicationFramework.Interfaces;
using GlobalDataItem = Neo.ApplicationFramework.Tools.OpcClient.GlobalDataItem;
using LightweightTag = Neo.ApplicationFramework.Tools.OpcClient.LightweightTag;
public partial class Screen1
{
void Button_Click(System.Object sender, System.EventArgs e)
{
GlobalDataItem tag = Tags.StringToTag<GlobalDataItem>("Tag1");
if (tag == null)
{
LightweightTag tag2 = Tags.StringToTag<LightweightTag>("Tag1");
if (tag2 == null)
{
MessageBox.Show("Error");
}
else
{
MessageBox.Show(tag2.Value.ToString());
}
}
else
{
MessageBox.Show(tag.Value.ToString());
}
}
}
}
If you only want to use the tag's "Value" property, you could also add the following to the Tags script to reduce coding elsewhere:
Code: Select all
public VariantValue this[string tagName]
{
get
{
GlobalDataItem GDI = Tags.StringToTag<GlobalDataItem>(tagName);
if (GDI == null)
{
LightweightTag LWT = Tags.StringToTag<LightweightTag>(tagName);
if (LWT == null)
throw new NotSupportedException(tagName);
else
return LWT.Value;
}
else
return GDI.Value;
}
set
{
GlobalDataItem GDI = Tags.StringToTag<GlobalDataItem>(tagName);
if (GDI == null)
{
LightweightTag LWT = Tags.StringToTag<LightweightTag>(tagName);
if (LWT == null)
throw new NotSupportedException(tagName);
else
LWT.Value = value;
}
else
GDI.Value = value;
}
}
This will enable you to use the code "Globals.Tags["Tag1"]" to read/write to Tag1. You may want to add a catch block just in case the function throws a "NotSupportedException". (Note: you will need to add the using remarks for GlobalDataItem and LightweightTag as in the Screen1 example in the Tags script.)
Hope this helps.
Adam M.
Controls Engineer
FlexEnergy