Introduction
This is for Sym3 Operator only.
Sym3 Operator comes with predefined 2D controls (Button, Panel, Alarm Grid, etc…). To provide extensibility, Sym3 Operator allows users to create their own window controls with the Host Control feature.
They are developed using Microsoft .Net Framework 4.8. The example below is written in the C# language.
A control is a Windows Forms User Control. The user can:
- Create a simple UserControl that doesn’t implement any interfaces from Sym3. In that case, the control has no way to interact with Sym3.
- Create a UserControl that implements the following Sym3 interface:
IHostedControl
. The control will then have access to the MacroAPI entry point:Client
.
Prerequisites
- Microsoft Visual Studio (2019 or 2022).
- Some knowledge of .Net and C#.
- Sym3 Operator installed and licensed.
Creation of the library (DLL)
First, we need to create a library (.dll) that will contain one or more controls. In this example, Visual Studio 2022 is used.
-
Open Visual Studio and create a new project
-
We need to create a ‘Windows Forms Control Library’:
-
Set the project Name, for example:
MyCompany.Sym3.MyControls
, use the.NET Framework 4.8
and press Create:
Creation of a standard user control
-
Create a User control and give it a name:
-
Now, we can start designing our control and implement the code behind:
-
Optionally, if you need to have access to the parameters (set in your .s3o project), you can implement this public function. Sym3 will automatically call this function after the control has been created:
public void Init(string parameters)
{
label1.Text = parameters; // example
}
Creation of a Sym3 compatible user control (recommended way)
-
A UserControl named
UserControl1
has been previously created, rename it toUserControlGauge
: -
We want this control to have access to Sym3’s API, the first step is to add a reference to those DLLs (located in
C:\Program Files\Sym3\Sym3 Operator\Client
): -
Then, we need to implement the interface
IHostedControl
:
using BCS.Sym3;
using BCS.Sym3.Operator.Runtime;
namespace MyCompany.Sym3.MyControls
{
public partial class UserControlGauge: UserControl, IHostedControl
{
public UserControlGauge()
{
InitializeComponent();
}
public void BeforeDispose()
{
}
void IHostedControl.Load(ControlRunningMode mode, ISym3OperatorClient Client, ISym3OperatorEditor Editor, string parameters)
{
}
}
}
- When the control is used in Sym3 Operator Client, the
Load
function is called and theClient
parameter will give us access to the Sym3 API, for example:
private ISym3OperatorClient Client;
private int m_min;
private int m_max;
void IHostedControl.Load(ControlRunningMode mode, ISym3OperatorClient Client, ISym3OperatorEditor Editor, string parameters)
{
this.Client = Client;
if (mode == ControlRunningMode.Design)
{
// This part of the code is executed, when the control is loaded in the design mode of Sym3 Operator Editor
}
else if (mode == ControlRunningMode.Preview)
{
// This part of the code is executed, when the control is previewed (in Sym3 Operator Editor, when previewing the window)
}
if (mode == ControlRunningMode.Run)
{
// This part of he code is executed when the control is actually loaded in Sym3 Operator Client.
// split parameters, for example if the parameter = "min=0;max=100"
string[] strs = parameters.Split(';');
foreach (string s in strs)
{
string[] array = s.Split('=');
if (array[0] == "min")
m_min = int.Parse(array[1]);
if (array[0] == "max")
m_max = int.Parse(array[1]);
}
// implement your code HERE
}
}
Interact with Tags
To read and write tags, your control will need to subscribe to the LiveValueService
, example
Client.Project.LiveValueService.Subscribe(this, m_tagName, m_tagName);
And for this to work, your control has to implement the IBindingNotification
interface. Example
public partial class UserControlGauge : UserControl, BCS.Sym3.IHostedControl, IBindingNotification
{
...
#region IBindingNotification Members
public void SubscribeLiveValue(object caller)
{
if (client == null) return;
if (client.Project == null) return;
if (client.Project.LiveValueService == null) return;
//-- subscribe to live value service
client.Project.LiveValueService.Subscribe(this, m_tagName, m_tagName);
}
public void UnsubscribeLiveValue()
{
if (client == null) return;
if (client.Project == null) return;
if (client.Project.LiveValueService == null) return;
client.Project.LiveValueService.Unsubscribe(this);
}
public bool SetLiveValue(string propertyName, object value)
{
return true;
}
public bool GetLiveValue(string propertyName, out object value, out BCS.Quality quality, bool useTagValue = false)
{
quality = Quality.BAD;
value = null;
return false;
}
public void UpdateBinding(string propertyName, int index, object value, BCS.Quality quality)
{
if (m_tagName == propertyName)
{
SetValue(m_tagName, value);
return;
}
}
#endregion
private void SetValue(string tagName, object value)
{
if(value == null) return;
double d = 0.0;
Double.TryParse(value.ToString(), out d);
if (d < m_min)
d = m_min;
if (d > m_max)
d = m_max;
progressBar1.Value = (int)d;
}
}
Build/Deployment
You will need to:
- Build your library in Release mode.
- Copy the DLL in
C:\Program Files\Sym3\Sym3 Operator\Client
. - Configure your project:
- Assembly Full Name =
C:\Program Files\Sym3\Sym3 Operator\Client\MyCompany.Sym3.MyControls.dll
- Class Name =
MyCompany.Sym3.MyControls.UserControlSimple
- Parameters =
Hello world
- Assembly Full Name =
Example
You can download an example of a library that contains:
- A vertical gauge.
- A horizontal gauge.