();
+
+ foreach (ListViewItem item in ItemsLV.SelectedItems)
+ {
+ itemsToDelete.Add(item);
+ }
+
+ foreach (ListViewItem item in itemsToDelete)
+ {
+ item.Remove();
+ }
+ }
+
+ ///
+ /// Compares two items in the list.
+ ///
+ protected virtual int CompareItems(object item1, object item2)
+ {
+ IComparable comparable = item1 as IComparable;
+
+ if (comparable != null)
+ {
+ return comparable.CompareTo(item2);
+ }
+
+ return 0;
+ }
+
+ ///
+ /// Returns the data to drag.
+ ///
+ protected virtual object GetDataToDrag()
+ {
+ if (ItemsLV.SelectedItems.Count > 0)
+ {
+ ArrayList data = new ArrayList();
+
+ foreach (ListViewItem listItem in ItemsLV.SelectedItems)
+ {
+ data.Add(listItem.Tag);
+ }
+
+ return data.ToArray();
+ }
+
+ return null;
+ }
+
+ ///
+ /// Adds an item to the list.
+ ///
+ protected virtual ListViewItem AddItem(object item)
+ {
+ return AddItem(item, "SimpleItem", -1);
+ }
+
+ ///
+ /// Adds an item to the list.
+ ///
+ protected virtual ListViewItem AddItem(object item, string icon, int index)
+ {
+ // switch to detail view as soon as an item is added.
+ if (ItemsLV.View == View.List)
+ {
+ ItemsLV.Items.Clear();
+ ItemsLV.View = View.Details;
+ }
+
+ ListViewItem listItem = null;
+
+ if (m_updating)
+ {
+ if (m_updateCount < ItemsLV.Items.Count)
+ {
+ listItem = ItemsLV.Items[m_updateCount];
+ }
+
+ m_updateCount++;
+ }
+
+ if (listItem == null)
+ {
+ listItem = new ListViewItem();
+ }
+
+ listItem.Text = String.Format("{0}", item);
+ listItem.ImageKey = icon;
+ listItem.Tag = item;
+
+ // fill columns with blanks.
+ for (int ii = listItem.SubItems.Count; ii < ItemsLV.Columns.Count-1; ii++)
+ {
+ listItem.SubItems.Add(String.Empty);
+ }
+
+ // calculate new index.
+ int newIndex = index;
+
+ if (index < 0 || index > ItemsLV.Items.Count)
+ {
+ newIndex = ItemsLV.Items.Count;
+ }
+
+ // update columns.
+ UpdateItem(listItem, item, newIndex);
+
+ if (listItem.ListView == null)
+ {
+ // add to control.
+ if (index >= 0 && index <= ItemsLV.Items.Count)
+ {
+ ItemsLV.Items.Insert(index, listItem);
+ }
+ else
+ {
+ ItemsLV.Items.Add(listItem);
+ }
+ }
+
+ NotifyItemAdded(item);
+
+ // return new item.
+ return listItem;
+ }
+
+ ///
+ /// Starts overwriting the contents of the control.
+ ///
+ protected void BeginUpdate()
+ {
+ m_updating = true;
+ m_updateCount = 0;
+ }
+
+ ///
+ /// Finishes overwriting the contents of the control.
+ ///
+ protected void EndUpdate()
+ {
+ m_updating = false;
+
+ while (ItemsLV.Items.Count > m_updateCount)
+ {
+ ItemsLV.Items[ItemsLV.Items.Count-1].Remove();
+ }
+
+ m_updateCount = 0;
+ AdjustColumns();
+ }
+
+ ///
+ /// Updates a list item with the current contents of an object.
+ ///
+ protected virtual void UpdateItem(ListViewItem listItem, object item)
+ {
+ listItem.Tag = item;
+ }
+
+ ///
+ /// Updates a list item with the current contents of an object.
+ ///
+ protected virtual void UpdateItem(ListViewItem listItem, object item, int index)
+ {
+ UpdateItem(listItem, item);
+ }
+
+ ///
+ /// Sets the columns shown in the list view.
+ ///
+ protected virtual void SetColumns(object[][] columns)
+ {
+ ItemsLV.Clear();
+
+ m_columns = columns;
+
+ foreach (object[] column in columns)
+ {
+ ColumnHeader header = new ColumnHeader();
+
+ header.Text = column[0] as string;
+ header.TextAlign = (HorizontalAlignment)column[1];
+
+ ItemsLV.Columns.Add(header);
+ }
+
+ ColumnHeader blank = new ColumnHeader();
+ blank.Text = String.Empty;
+ ItemsLV.Columns.Add(blank);
+
+ AdjustColumns();
+ }
+
+ ///
+ /// Adjusts the columns shown in the list view.
+ ///
+ protected virtual void AdjustColumns()
+ {
+ if (ItemsLV.View == View.List || ItemsLV.Items.Count == 0)
+ {
+ ItemsLV.View = View.List;
+
+ if (ItemsLV.Items.Count == 0 && !String.IsNullOrEmpty(m_instructions))
+ {
+ ListViewItem item = new ListViewItem(m_instructions);
+
+ item.ImageKey = "Info";
+ item.ForeColor = Color.Gray;
+
+ ItemsLV.Items.Add(item);
+ }
+
+ ItemsLV.Columns[0].Width = -2;
+ return;
+ }
+
+ ItemsLV.View = View.Details;
+
+ for (int ii = 0; ii < m_columns.Length && ii < ItemsLV.Columns.Count; ii++)
+ {
+ // check for fixed width columns.
+ if (m_columns[ii].Length >= 4 && m_columns[ii][3] != null)
+ {
+ int width = (int)m_columns[ii][3];
+
+ if (ItemsLV.Columns[ii].Width < width)
+ {
+ ItemsLV.Columns[ii].Width = width;
+ }
+
+ continue;
+ }
+
+ // check mandatory columns.
+ if (m_columns[ii].Length < 3 || m_columns[ii][2] == null)
+ {
+ ItemsLV.Columns[ii].Width = -2;
+ continue;
+ }
+
+ // check if all items have the default value for the column.
+ bool display = false;
+
+ foreach (ListViewItem listItem in ItemsLV.Items)
+ {
+ if (!m_columns[ii][2].Equals(listItem.SubItems[ii].Text))
+ {
+ display = true;
+ break;
+ }
+ }
+
+ // only display columns with non-default information.
+ if (display)
+ {
+ ItemsLV.Columns[ii].Width = -2;
+ }
+ else
+ {
+ ItemsLV.Columns[ii].Width = 0;
+ }
+ }
+
+ if (ItemsLV.Columns.Count > 0)
+ {
+ ItemsLV.Columns[ItemsLV.Columns.Count-1].Width = 0;
+ }
+ }
+
+ ///
+ /// Enables the state of menu items.
+ ///
+ protected virtual void EnableMenuItems(ListViewItem clickedItem)
+ {
+ // do nothing.
+ }
+
+ ///
+ /// Sends notifications whenever items in the control are 'picked'.
+ ///
+ protected virtual void PickItems()
+ {
+ if (m_ItemsPicked != null)
+ {
+ ICollection data = GetDataToDrag() as ICollection;
+
+ if (data != null)
+ {
+ m_ItemsPicked(this, new ListItemActionEventArgs(ListItemAction.Picked, data));
+ }
+ }
+ }
+
+ ///
+ /// Sends notifications whenever items in the control are 'selected'.
+ ///
+ protected virtual void SelectItems()
+ {
+ if (m_ItemsSelected != null)
+ {
+ object[] selectedObjects = new object[ItemsLV.SelectedItems.Count];
+
+ for (int ii = 0; ii < selectedObjects.Length; ii++)
+ {
+ selectedObjects[ii] = ItemsLV.SelectedItems[ii].Tag;
+ }
+
+ m_ItemsSelected(this, new ListItemActionEventArgs(ListItemAction.Selected, selectedObjects));
+ }
+ }
+
+ ///
+ /// Sends notifications that an item has been added to the control.
+ ///
+ protected virtual void NotifyItemAdded(object item)
+ {
+ NotifyItemsAdded(new object[] { item });
+ }
+
+ ///
+ /// Sends notifications that items have been added to the control.
+ ///
+ protected virtual void NotifyItemsAdded(object[] items)
+ {
+ if (m_ItemsAdded != null && items != null && items.Length > 0)
+ {
+ m_ItemsAdded(this, new ListItemActionEventArgs(ListItemAction.Added, items));
+ }
+ }
+
+ ///
+ /// Sends notifications that an item has been modified in the control.
+ ///
+ protected virtual void NotifyItemModified(object item)
+ {
+ NotifyItemsModified(new object[] { item });
+ }
+
+ ///
+ /// Sends notifications that items have been modified in the control.
+ ///
+ protected virtual void NotifyItemsModified(object[] items)
+ {
+ if (m_ItemsModified != null && items != null && items.Length > 0)
+ {
+ m_ItemsModified(this, new ListItemActionEventArgs(ListItemAction.Modified, items));
+ }
+ }
+
+ ///
+ /// Sends notifications that and item has been removed from the control.
+ ///
+ protected virtual void NotifyItemRemoved(object item)
+ {
+ NotifyItemsRemoved(new object[] { item });
+ }
+
+ ///
+ /// Sends notifications that items have been removed from the control.
+ ///
+ protected virtual void NotifyItemsRemoved(object[] items)
+ {
+ if (m_ItemsRemoved != null && items != null && items.Length > 0)
+ {
+ m_ItemsRemoved(this, new ListItemActionEventArgs(ListItemAction.Removed, items));
+ }
+ }
+
+ ///
+ /// Finds the list item with specified tag in the control,
+ ///
+ protected ListViewItem FindItem(object tag)
+ {
+ foreach (ListViewItem listItem in ItemsLV.Items)
+ {
+ if (Object.ReferenceEquals(tag, listItem.Tag))
+ {
+ return listItem;
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// Returns the tag associated with a selected item.
+ ///
+ protected object GetSelectedTag(int index)
+ {
+ if (ItemsLV.SelectedItems.Count > index)
+ {
+ return ItemsLV.SelectedItems[index].Tag;
+ }
+
+ return null;
+ }
+ #endregion
+
+ #region BaseListCtrlSorter Class
+ ///
+ /// A class that allows the list to be sorted.
+ ///
+ private class BaseListCtrlSorter : IComparer
+ {
+ ///
+ /// Initializes the sorter.
+ ///
+ public BaseListCtrlSorter(BaseListCtrl control)
+ {
+ m_control = control;
+ }
+
+ ///
+ /// Compares the two items.
+ ///
+ public int Compare(object x, object y)
+ {
+ ListViewItem itemX = x as ListViewItem;
+ ListViewItem itemY = y as ListViewItem;
+
+ return m_control.CompareItems(itemX.Tag, itemY.Tag);
+ }
+
+ private BaseListCtrl m_control;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void ItemsLV_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ try
+ {
+ // ignore non-right clicks.
+ if (e.Button == MouseButtons.Left)
+ {
+ m_dragPosition = e.Location;
+ return;
+ }
+
+ // disable everything.
+ if (ItemsLV.ContextMenuStrip != null)
+ {
+ foreach (ToolStripItem item in ItemsLV.ContextMenuStrip.Items)
+ {
+ ToolStripMenuItem menuItem = item as ToolStripMenuItem;
+
+ if (menuItem == null)
+ {
+ continue;
+ }
+
+ menuItem.Enabled = false;
+
+ if (menuItem.DropDown != null)
+ {
+ foreach (ToolStripItem subItem in menuItem.DropDown.Items)
+ {
+ ToolStripMenuItem subMenuItem = subItem as ToolStripMenuItem;
+
+ if (subMenuItem != null)
+ {
+ subMenuItem.Enabled = false;
+ }
+ }
+ }
+ }
+ }
+
+ // selects the item that was right clicked on.
+ ListViewItem clickedItem = ItemsLV.GetItemAt(e.X, e.Y);
+
+ // ensure clicked item is selected.
+ if (clickedItem != null)
+ {
+ clickedItem.Selected = true;
+ }
+
+ // enable menu items according to context.
+ EnableMenuItems(clickedItem);
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ItemsLV_MouseUp(object sender, MouseEventArgs e)
+ {
+ try
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ m_dragPosition = e.Location;
+ return;
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ItemsLV_DoubleClick(object sender, System.EventArgs e)
+ {
+ try
+ {
+ PickItems();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ItemsLV_SelectedIndexChanged(object sender, System.EventArgs e)
+ {
+ try
+ {
+ SelectItems();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ItemsLV_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (m_enableDragging && e.Button == MouseButtons.Left && !m_dragPosition.Equals(e.Location))
+ {
+ object data = GetDataToDrag();
+
+ if (data != null)
+ {
+ ItemsLV.DoDragDrop(data, DragDropEffects.Copy);
+ }
+ }
+ }
+
+ ///
+ /// Handles the DragEnter event of the ItemsLV control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected virtual void ItemsLV_DragEnter(object sender, DragEventArgs e)
+ {
+ if (m_enableDragging)
+ {
+ e.Effect = DragDropEffects.Copy;
+ }
+ else
+ {
+ e.Effect = DragDropEffects.None;
+ }
+ }
+
+ ///
+ /// Handles the DragDrop event of the ItemsLV control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected virtual void ItemsLV_DragDrop(object sender, DragEventArgs e)
+ {
+ // overriden by sub-class.
+ }
+ #endregion
+ }
+
+ #region ListItemAction Enumeration
+ ///
+ /// The possible actions that could affect an item.
+ ///
+ public enum ListItemAction
+ {
+
+ ///
+ /// The item was picked (double clicked).
+ ///
+ Picked,
+
+ ///
+ /// The item was selected.
+ ///
+ Selected,
+
+ ///
+ /// The item was added.
+ ///
+ Added,
+
+ ///
+ /// The item was modified.
+ ///
+ Modified,
+
+ ///
+ /// The item was removed.
+ ///
+ Removed
+ }
+ #endregion
+
+ #region ListItemActionEventArgs Class
+ ///
+ /// The event argurments passed when an item event occurs.
+ ///
+ public class ListItemActionEventArgs : EventArgs
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The action.
+ /// The items.
+ public ListItemActionEventArgs(ListItemAction action, ICollection items)
+ {
+ m_items = items;
+ m_action = action;
+ }
+ #endregion
+
+ #region Public Properties
+ ///
+ /// Gets the items.
+ ///
+ /// The items.
+ public ICollection Items
+ {
+ get { return m_items; }
+ }
+
+ ///
+ /// Gets the action.
+ ///
+ /// The action.
+ public ListItemAction Action
+ {
+ get { return m_action; }
+ }
+ #endregion
+
+ #region Private Fields
+ private ICollection m_items;
+ private ListItemAction m_action;
+ #endregion
+ }
+
+ ///
+ /// The delegate used to receive item action events.
+ ///
+ public delegate void ListItemActionEventHandler(object sender, ListItemActionEventArgs e);
+ #endregion
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseListCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseListCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseListCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.Designer.cs
new file mode 100644
index 00000000..c3775947
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.Designer.cs
@@ -0,0 +1,93 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class BaseTreeCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.NodesTV = new System.Windows.Forms.TreeView();
+ this.SuspendLayout();
+ //
+ // NodesTV
+ //
+ this.NodesTV.AllowDrop = true;
+ this.NodesTV.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.NodesTV.Location = new System.Drawing.Point(0, 0);
+ this.NodesTV.Name = "NodesTV";
+ this.NodesTV.Size = new System.Drawing.Size(489, 397);
+ this.NodesTV.TabIndex = 1;
+ this.NodesTV.GiveFeedback += new System.Windows.Forms.GiveFeedbackEventHandler(this.NodesTV_GiveFeedback);
+ this.NodesTV.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.NodesTV_BeforeExpand);
+ this.NodesTV.DoubleClick += new System.EventHandler(this.NodesTV_DoubleClick);
+ this.NodesTV.DragDrop += new System.Windows.Forms.DragEventHandler(this.NodesTV_DragDrop);
+ this.NodesTV.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.NodesTV_AfterSelect);
+ this.NodesTV.MouseDown += new System.Windows.Forms.MouseEventHandler(this.NodesTV_MouseDown);
+ this.NodesTV.DragEnter += new System.Windows.Forms.DragEventHandler(this.NodesTV_DragEnter);
+ this.NodesTV.DragOver += new System.Windows.Forms.DragEventHandler(this.NodesTV_DragOver);
+ //
+ // BaseTreeCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.NodesTV);
+ this.Name = "BaseTreeCtrl";
+ this.Size = new System.Drawing.Size(489, 397);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.cs
new file mode 100644
index 00000000..fa6b72ec
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.cs
@@ -0,0 +1,456 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A base class for tree controls.
+ ///
+ public partial class BaseTreeCtrl : UserControl
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public BaseTreeCtrl()
+ {
+ InitializeComponent();
+ NodesTV.ImageList = new GuiUtils().ImageList;
+ NodesTV.ItemHeight = 18;
+ }
+
+ #region Public Interface
+ ///
+ /// The TreeView contained in the Control.
+ ///
+ protected System.Windows.Forms.TreeView NodesTV;
+
+ ///
+ /// Raised whenever a node is 'picked' in the control.
+ ///
+ public event TreeNodeActionEventHandler NodePicked
+ {
+ add { m_NodePicked += value; }
+ remove { m_NodePicked -= value; }
+ }
+
+ ///
+ /// Raised whenever a node is selected in the control.
+ ///
+ public event TreeNodeActionEventHandler NodeSelected
+ {
+ add { m_NodeSelected += value; }
+ remove { m_NodeSelected -= value; }
+ }
+
+ ///
+ /// Whether the control should allow items to be dragged.
+ ///
+ public bool EnableDragging
+ {
+ get { return m_enableDragging; }
+ set { m_enableDragging = value; }
+ }
+ #endregion
+
+ #region Private Fields
+ private event TreeNodeActionEventHandler m_NodePicked;
+ private event TreeNodeActionEventHandler m_NodeSelected;
+ private bool m_enableDragging;
+ #endregion
+
+ #region Protected Methods
+ ///
+ /// Adds an item to the tree.
+ ///
+ protected virtual TreeNode AddNode(TreeNode treeNode, object item)
+ {
+ return AddNode(treeNode, item, String.Format("{0}", item), "ClosedFolder");
+ }
+
+ ///
+ /// Adds an item to the tree.
+ ///
+ protected virtual TreeNode AddNode(TreeNode parent, object item, string text, string icon)
+ {
+ // create node.
+ TreeNode treeNode = new TreeNode();
+
+ // update text/icon.
+ UpdateNode(treeNode, item, text, icon);
+
+ // add to control.
+ if (parent == null)
+ {
+ NodesTV.Nodes.Add(treeNode);
+ }
+ else
+ {
+ parent.Nodes.Add(treeNode);
+ }
+
+ // return new tree node.
+ return treeNode;
+ }
+
+ ///
+ /// Updates a tree node with the current contents of an object.
+ ///
+ protected virtual void UpdateNode(TreeNode treeNode, object item, string text, string icon)
+ {
+ treeNode.Text = text;
+ treeNode.Tag = item;
+ treeNode.ImageKey = icon;
+ treeNode.SelectedImageKey = icon;
+ }
+
+ ///
+ /// Returns the data to drag.
+ ///
+ protected virtual object GetDataToDrag(TreeNode node)
+ {
+ return node.Tag;
+ }
+
+ ///
+ /// Enables the state of menu items.
+ ///
+ protected virtual void EnableMenuItems(TreeNode clickedNode)
+ {
+ // do nothing.
+ }
+
+ ///
+ /// Initializes a node before expanding it.
+ ///
+ protected virtual bool BeforeExpand(TreeNode clickedNode)
+ {
+ return false;
+ }
+
+ ///
+ /// Sends notifications whenever a node in the control is 'picked'.
+ ///
+ protected virtual void PickNode()
+ {
+ if (m_NodePicked != null)
+ {
+ if (NodesTV.SelectedNode != null)
+ {
+ object parent = null;
+
+ if (NodesTV.SelectedNode.Parent != null)
+ {
+ parent = NodesTV.SelectedNode.Tag;
+ }
+
+ m_NodePicked(this, new TreeNodeActionEventArgs(TreeNodeAction.Picked, NodesTV.SelectedNode.Tag, parent));
+ }
+ }
+ }
+
+ ///
+ /// Sends notifications whenever a node in the control is 'selected'.
+ ///
+ protected virtual void SelectNode()
+ {
+ if (m_NodeSelected != null)
+ {
+ if (NodesTV.SelectedNode != null)
+ {
+ object parent = null;
+
+ if (NodesTV.SelectedNode.Parent != null)
+ {
+ parent = NodesTV.SelectedNode.Tag;
+ }
+
+ m_NodeSelected(this, new TreeNodeActionEventArgs(TreeNodeAction.Selected, NodesTV.SelectedNode.Tag, parent));
+ }
+ }
+ }
+
+ ///
+ /// Returns the Tag for the current selection.
+ ///
+ protected object SelectedTag
+ {
+ get
+ {
+ if (NodesTV.SelectedNode != null)
+ {
+ return NodesTV.SelectedNode.Tag;
+ }
+
+ return null;
+ }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void NodesTV_AfterSelect(object sender, TreeViewEventArgs e)
+ {
+ try
+ {
+ SelectNode();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void NodesTV_BeforeExpand(object sender, TreeViewCancelEventArgs e)
+ {
+ try
+ {
+ Cursor = Cursors.WaitCursor;
+ e.Cancel = BeforeExpand(e.Node);
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ finally
+ {
+ Cursor = Cursors.Default;
+ }
+ }
+
+ private void NodesTV_DoubleClick(object sender, EventArgs e)
+ {
+ try
+ {
+ PickNode();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void NodesTV_MouseDown(object sender, MouseEventArgs e)
+ {
+ try
+ {
+ // selects the item that was right clicked on.
+ TreeNode clickedNode = NodesTV.SelectedNode = NodesTV.GetNodeAt(e.X, e.Y);
+
+ // no item clicked on - do nothing.
+ if (clickedNode == null) return;
+
+ // start drag operation.
+ if (e.Button == MouseButtons.Left)
+ {
+ if (m_enableDragging)
+ {
+ object data = GetDataToDrag(clickedNode);
+
+ if (data != null)
+ {
+ NodesTV.DoDragDrop(data, DragDropEffects.Copy);
+ }
+ }
+
+ return;
+ }
+
+ // disable everything.
+ if (NodesTV.ContextMenuStrip != null)
+ {
+ foreach (ToolStripItem item in NodesTV.ContextMenuStrip.Items)
+ {
+ ToolStripMenuItem menuItem = item as ToolStripMenuItem;
+
+ if (menuItem == null)
+ {
+ continue;
+ }
+
+ menuItem.Enabled = false;
+
+ if (menuItem.DropDown != null)
+ {
+ foreach (ToolStripItem subItem in menuItem.DropDown.Items)
+ {
+ ToolStripMenuItem subMenuItem = subItem as ToolStripMenuItem;
+
+ if (subMenuItem != null)
+ {
+ subMenuItem.Enabled = false;
+ }
+ }
+ }
+ }
+ }
+
+ // enable menu items according to context.
+ if (e.Button == MouseButtons.Right)
+ {
+ EnableMenuItems(clickedNode);
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ ///
+ /// Handles the DragEnter event of the NodesTV control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected virtual void NodesTV_DragEnter(object sender, DragEventArgs e)
+ {
+ if (m_enableDragging)
+ {
+ e.Effect = DragDropEffects.Copy;
+ }
+ else
+ {
+ e.Effect = DragDropEffects.None;
+ }
+ }
+
+ ///
+ /// Handles the DragDrop event of the NodesTV control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected virtual void NodesTV_DragDrop(object sender, DragEventArgs e)
+ {
+ // overridden by sub-class.
+ }
+
+ ///
+ /// Handles the GiveFeedback event of the NodesTV control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected virtual void NodesTV_GiveFeedback(object sender, GiveFeedbackEventArgs e)
+ {
+ // overridden by sub-class.
+ }
+
+ ///
+ /// Handles the DragOver event of the NodesTV control.
+ ///
+ /// The source of the event.
+ /// The instance containing the event data.
+ protected virtual void NodesTV_DragOver(object sender, DragEventArgs e)
+ {
+ // overridden by sub-class.
+ }
+ #endregion
+ }
+
+ #region TreeNodeAction Eumeration
+ ///
+ /// The possible actions that could affect a node.
+ ///
+ public enum TreeNodeAction
+ {
+ ///
+ /// A node was picked in the tree.
+ ///
+ Picked,
+
+ ///
+ /// A node was selected in the tree.
+ ///
+ Selected
+ }
+ #endregion
+
+ #region TreeNodeActionEventArgs class
+ ///
+ /// The event argurments passed when an node event occurs.
+ ///
+ public class TreeNodeActionEventArgs : EventArgs
+ {
+ #region Constructor
+ ///
+ /// Initializes the object.
+ ///
+ public TreeNodeActionEventArgs(TreeNodeAction action, object node, object parent)
+ {
+ m_node = node;
+ m_parent = parent;
+ m_action = action;
+ }
+ #endregion
+
+ #region Private Fields
+ ///
+ /// The tag associated with the node that was acted on.
+ ///
+ public object Node
+ {
+ get { return m_node; }
+ }
+
+ ///
+ /// The tag associated with the parent of the node that was acted on.
+ ///
+ public object Parent
+ {
+ get { return m_parent; }
+ }
+
+ ///
+ /// The action in question.
+ ///
+ public TreeNodeAction Action
+ {
+ get { return m_action; }
+ }
+ #endregion
+
+ #region Private Fields
+ private object m_node;
+ private object m_parent;
+ private TreeNodeAction m_action;
+ #endregion
+ }
+
+ ///
+ /// The delegate used to receive node action events.
+ ///
+ public delegate void TreeNodeActionEventHandler(object sender, TreeNodeActionEventArgs e);
+ #endregion
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/BaseTreeCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ClipboardHack.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ClipboardHack.cs
new file mode 100644
index 00000000..bafaae01
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ClipboardHack.cs
@@ -0,0 +1,155 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.Threading;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// This class is used to work around a bug in the MS VPC implementation.
+ ///
+ ///
+ /// Clipborad operations will fail if this class is not used on VPCs with the
+ /// virtual machine additions installed.
+ ///
+ public static class ClipboardHack
+ {
+ #region Public Methods
+ ///
+ /// Retrieves the data from the clipboard.
+ ///
+ public static object GetData(string format)
+ {
+ lock (m_lock)
+ {
+ m_format = format;
+ m_data = null;
+ m_error = null;
+
+ Thread thread = new Thread(new ThreadStart(GetClipboardPrivate));
+ thread.IsBackground = true;
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+ thread.Join();
+
+ if (m_error != null)
+ {
+ throw new ServiceResultException(m_error, StatusCodes.BadUnexpectedError);
+ }
+
+ return m_data;
+ }
+ }
+
+ ///
+ /// Saves the data in the clipboard.
+ ///
+ public static void SetData(string format, object data)
+ {
+ lock (m_lock)
+ {
+ m_format = format;
+ m_data = data;
+ m_error = null;
+
+ Thread thread = new Thread(new ThreadStart(SetClipboardPrivate));
+ thread.IsBackground = true;
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+ thread.Join();
+
+ if (m_error != null)
+ {
+ throw new ServiceResultException(m_error, StatusCodes.BadUnexpectedError);
+ }
+ }
+ }
+ #endregion
+
+ #region Private Methods
+ ///
+ /// Gets the data in the clipboard if it is the correct format.
+ ///
+ private static void GetClipboardPrivate()
+ {
+ try
+ {
+ m_error = null;
+
+ if (String.IsNullOrEmpty(m_format) || !Clipboard.ContainsData(m_format))
+ {
+ m_data = null;
+ return;
+ }
+
+ m_data = Clipboard.GetData(m_format);
+ }
+ catch (Exception e)
+ {
+ m_error = e;
+ }
+ }
+
+ ///
+ /// Saves the data in the clipboard if it is the correct format.
+ ///
+ private static void SetClipboardPrivate()
+ {
+ try
+ {
+ m_error = null;
+
+ if (String.IsNullOrEmpty(m_format) || m_data == null)
+ {
+ return;
+ }
+
+ Clipboard.SetData(m_format, m_data);
+ }
+ catch (Exception e)
+ {
+ m_error = e;
+ }
+ }
+ #endregion
+
+ #region Private Fields
+ private static object m_lock = new object();
+ private static string m_format = null;
+ private static object m_data = null;
+ private static Exception m_error = null;
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.Designer.cs
new file mode 100644
index 00000000..c07e927f
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.Designer.cs
@@ -0,0 +1,150 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ComplexValueEditDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.ValueCTRL = new Opc.Ua.Client.Controls.DataListCtrl();
+ this.ButtonsPN.SuspendLayout();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 317);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(707, 28);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.Location = new System.Drawing.Point(4, 1);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(628, 1);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // panel1
+ //
+ this.panel1.Controls.Add(this.ValueCTRL);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel1.Location = new System.Drawing.Point(0, 0);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(707, 317);
+ this.panel1.TabIndex = 1;
+ //
+ // ValueCTRL
+ //
+ this.ValueCTRL.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ValueCTRL.AutoUpdate = true;
+ this.ValueCTRL.Instructions = null;
+ this.ValueCTRL.LatestValue = true;
+ this.ValueCTRL.Location = new System.Drawing.Point(4, 3);
+ this.ValueCTRL.MonitoredItem = null;
+ this.ValueCTRL.Name = "ValueCTRL";
+ this.ValueCTRL.Size = new System.Drawing.Size(699, 311);
+ this.ValueCTRL.TabIndex = 0;
+ //
+ // ComplexValueEditDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(707, 345);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "ComplexValueEditDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Edit Value";
+ this.ButtonsPN.ResumeLayout(false);
+ this.panel1.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel panel1;
+ private DataListCtrl ValueCTRL;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.cs
new file mode 100644
index 00000000..196baabd
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.cs
@@ -0,0 +1,106 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+using Opc.Ua.Client;
+using Opc.Ua.Client.Controls;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog to edit a complex value.
+ ///
+ public partial class ComplexValueEditDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ComplexValueEditDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Private Fields
+ private object m_value;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public object ShowDialog(object value)
+ {
+ return ShowDialog(value, null);
+ }
+
+ ///
+ /// Displays the dialog.
+ ///
+ public object ShowDialog(object value, MonitoredItem monitoredItem)
+ {
+ m_value = Utils.Clone(value);
+
+ ValueCTRL.MonitoredItem = monitoredItem;
+ ValueCTRL.ShowValue(m_value);
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_value;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ComplexValueEditDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.Designer.cs
new file mode 100644
index 00000000..a4cbae4a
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.Designer.cs
@@ -0,0 +1,145 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ ///
+ ///
+ partial class DataListCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.PopupMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.UpdatesMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.RefreshMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.ClearMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.Separator01 = new System.Windows.Forms.ToolStripSeparator();
+ this.EditMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.PopupMenu.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ItemsLV
+ //
+ this.ItemsLV.ContextMenuStrip = this.PopupMenu;
+ this.ItemsLV.MultiSelect = false;
+ this.ItemsLV.MouseClick += new System.Windows.Forms.MouseEventHandler(this.ItemsLV_MouseClick);
+ //
+ // PopupMenu
+ //
+ this.PopupMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.UpdatesMI,
+ this.RefreshMI,
+ this.ClearMI,
+ this.Separator01,
+ this.EditMI});
+ this.PopupMenu.Name = "PopupMenu";
+ this.PopupMenu.Size = new System.Drawing.Size(136, 98);
+ this.PopupMenu.Opening += new System.ComponentModel.CancelEventHandler(this.PopupMenu_Opening);
+ //
+ // UpdatesMI
+ //
+ this.UpdatesMI.Checked = true;
+ this.UpdatesMI.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.UpdatesMI.Name = "UpdatesMI";
+ this.UpdatesMI.Size = new System.Drawing.Size(135, 22);
+ this.UpdatesMI.Text = "Auto Update";
+ this.UpdatesMI.CheckedChanged += new System.EventHandler(this.UpdatesMI_CheckedChanged);
+ //
+ // RefreshMI
+ //
+ this.RefreshMI.Name = "RefreshMI";
+ this.RefreshMI.Size = new System.Drawing.Size(135, 22);
+ this.RefreshMI.Text = "Refresh";
+ this.RefreshMI.Click += new System.EventHandler(this.RefreshMI_Click);
+ //
+ // ClearMI
+ //
+ this.ClearMI.Name = "ClearMI";
+ this.ClearMI.Size = new System.Drawing.Size(135, 22);
+ this.ClearMI.Text = "Clear";
+ this.ClearMI.Click += new System.EventHandler(this.ClearMI_Click);
+ //
+ // Separator01
+ //
+ this.Separator01.Name = "Separator01";
+ this.Separator01.Size = new System.Drawing.Size(132, 6);
+ //
+ // EditMI
+ //
+ this.EditMI.Name = "EditMI";
+ this.EditMI.Size = new System.Drawing.Size(135, 22);
+ this.EditMI.Text = "Edit Value...";
+ this.EditMI.Click += new System.EventHandler(this.EditMI_Click);
+ //
+ // DataListCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.Name = "DataListCtrl";
+ this.Controls.SetChildIndex(this.ItemsLV, 0);
+ this.PopupMenu.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ContextMenuStrip PopupMenu;
+ private System.Windows.Forms.ToolStripMenuItem UpdatesMI;
+ private System.Windows.Forms.ToolStripMenuItem RefreshMI;
+ private System.Windows.Forms.ToolStripMenuItem ClearMI;
+ private System.Windows.Forms.ToolStripSeparator Separator01;
+ private System.Windows.Forms.ToolStripMenuItem EditMI;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.cs
new file mode 100644
index 00000000..078f57ee
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.cs
@@ -0,0 +1,1774 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Xml;
+using System.Xml.Serialization;
+
+using Opc.Ua.Client;
+using Opc.Ua.Client.Controls;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Displays a hierarchical view of a complex value.
+ ///
+ public partial class DataListCtrl : Opc.Ua.Client.Controls.BaseListCtrl
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DataListCtrl()
+ {
+ InitializeComponent();
+ SetColumns(m_ColumnNames);
+ }
+
+ #region Private Fields
+ ///
+ /// The columns to display in the control.
+ ///
+ private readonly object[][] m_ColumnNames = new object[][]
+ {
+ new object[] { "Name", HorizontalAlignment.Left, null },
+ new object[] { "Value", HorizontalAlignment.Left, null, 250 },
+ new object[] { "Type", HorizontalAlignment.Left, null }
+ };
+
+ private bool m_latestValue = true;
+ private bool m_expanding;
+ private int m_depth;
+ private Font m_defaultFont;
+ private MonitoredItem m_monitoredItem;
+
+ private const string UnknownType = "(unknown)";
+ private const string NullValue = "(null)";
+ private const string ExpandIcon = "ExpandPlus";
+ private const string CollapseIcon = "ExpandMinus";
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Whether to update the control when the value changes.
+ ///
+ public bool AutoUpdate
+ {
+ get { return UpdatesMI.Checked; }
+ set { UpdatesMI.Checked = value; }
+ }
+
+ ///
+ /// Whether to only display the latest value for a monitored item.
+ ///
+ public bool LatestValue
+ {
+ get { return m_latestValue; }
+ set { m_latestValue = value; }
+ }
+
+ ///
+ /// The monitored item associated with the value.
+ ///
+ public MonitoredItem MonitoredItem
+ {
+ get { return m_monitoredItem; }
+ set { m_monitoredItem = value; }
+ }
+
+ ///
+ /// Clears the contents of the control,
+ ///
+ public void Clear()
+ {
+ ItemsLV.Items.Clear();
+ AdjustColumns();
+ }
+
+ ///
+ /// Displays a value in the control.
+ ///
+ public void ShowValue(object value)
+ {
+ ShowValue(value, false);
+ }
+
+ ///
+ /// Displays a value in the control.
+ ///
+ public void ShowValue(object value, bool overwrite)
+ {
+ if (!overwrite)
+ {
+ Clear();
+ }
+
+ if (value is byte[])
+ {
+ m_defaultFont = new Font("Courier New", 8.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
+ }
+ else
+ {
+ m_defaultFont = ItemsLV.Font;
+ }
+
+ m_expanding = false;
+ m_depth = 0;
+
+ // show the value.
+ int index = 0;
+ ShowValue(ref index, ref overwrite, value);
+
+ // adjust columns.
+ AdjustColumns();
+ }
+ #endregion
+
+ #region Overridden Methods
+ ///
+ /// Enables the menu items.
+ ///
+ protected override void EnableMenuItems(ListViewItem clickedItem)
+ {
+ RefreshMI.Enabled = true;
+ ClearMI.Enabled = true;
+
+ if (ItemsLV.SelectedItems.Count == 1)
+ {
+ ValueState state = ItemsLV.SelectedItems[0].Tag as ValueState;
+ EditMI.Enabled = IsEditableType(state.Component);
+ }
+ }
+ #endregion
+
+ #region ValueState Class
+ ///
+ /// Stores the state associated with an item.
+ ///
+ private class ValueState
+ {
+ public bool Expanded = false;
+ public bool Expandable = false;
+ public object Value = null;
+ public object Component = null;
+ public object ComponentId = null;
+ public object ComponentIndex = null;
+ }
+ #endregion
+
+ #region Private Members
+ ///
+ /// Returns true is the value is an editable type.
+ ///
+ private bool IsEditableType(object value)
+ {
+ if (value is bool) return true;
+ if (value is sbyte) return true;
+ if (value is byte) return true;
+ if (value is short) return true;
+ if (value is ushort) return true;
+ if (value is int) return true;
+ if (value is uint) return true;
+ if (value is long) return true;
+ if (value is ulong) return true;
+ if (value is float) return true;
+ if (value is double) return true;
+ if (value is string) return true;
+ if (value is DateTime) return true;
+ if (value is Guid) return true;
+ if (value is LocalizedText) return true;
+
+ return false;
+ }
+
+ ///
+ /// Shows the components of a value in the control.
+ ///
+ private void ShowChildren(ListViewItem listItem)
+ {
+ ValueState state = listItem.Tag as ValueState;
+
+ if (state == null || !state.Expandable || state.Expanded)
+ {
+ return;
+ }
+
+ m_expanding = true;
+ m_depth = listItem.IndentCount+1;
+
+ state.Expanded = true;
+ listItem.ImageKey = CollapseIcon;
+
+ int index = listItem.Index+1;
+ bool overwrite = false;
+
+ ShowValue(ref index, ref overwrite, state.Component);
+
+ AdjustColumns();
+ }
+
+ ///
+ /// Hides the components of a value in the control.
+ ///
+ private void HideChildren(ListViewItem listItem)
+ {
+ ValueState state = listItem.Tag as ValueState;
+
+ if (state == null || !state.Expandable || !state.Expanded)
+ {
+ return;
+ }
+
+ for (int ii = listItem.Index+1; ii < ItemsLV.Items.Count;)
+ {
+ ListViewItem childItem = ItemsLV.Items[ii];
+
+ if (childItem.IndentCount <= listItem.IndentCount)
+ {
+ break;
+ }
+
+ childItem.Remove();
+ }
+
+ state.Expanded = false;
+ listItem.ImageKey = ExpandIcon;
+ }
+
+ ///
+ /// Returns the list item at the specified index.
+ ///
+ private ListViewItem GetListItem(int index, ref bool overwrite, string name, string type)
+ {
+ ListViewItem listitem = null;
+
+ // switch to detail view as soon as an item is added.
+ if (ItemsLV.View == View.List)
+ {
+ ItemsLV.Items.Clear();
+ ItemsLV.View = View.Details;
+ }
+
+ // check if there is an item that could be re-used.
+ if (!m_expanding && index < ItemsLV.Items.Count)
+ {
+ listitem = ItemsLV.Items[index];
+
+ // check if still possible to overwrite values.
+ if (overwrite)
+ {
+ if (listitem.SubItems[0].Text != name || listitem.SubItems[2].Text != type)
+ {
+ overwrite = false;
+ }
+ }
+
+ listitem.SubItems[0].Text = name;
+ listitem.SubItems[2].Text = type;
+
+ return listitem;
+ }
+
+ overwrite = false;
+
+ listitem = new ListViewItem(name);
+
+ listitem.SubItems.Add(String.Empty);
+ listitem.SubItems.Add(type);
+
+ listitem.Font = m_defaultFont;
+ listitem.ImageKey = ExpandIcon;
+ listitem.IndentCount = m_depth;
+ listitem.Tag = new ValueState();
+
+ if (!m_expanding)
+ {
+ ItemsLV.Items.Add(listitem);
+ }
+ else
+ {
+ ItemsLV.Items.Insert(index, listitem);
+ }
+
+ return listitem;
+ }
+
+ ///
+ /// Returns true if the type can be expanded.
+ ///
+ private bool IsExpandableType(object value)
+ {
+ // check for null.
+ if (value == null)
+ {
+ return false;
+ }
+
+ // check for Variant.
+ if (value is Variant)
+ {
+ return IsExpandableType(((Variant)value).Value);
+ }
+
+ // check for bytes.
+ byte[] bytes = value as byte[];
+
+ if (bytes != null)
+ {
+ return false;
+ }
+
+ // check for xml element.
+ XmlElement xml = value as XmlElement;
+
+ if (xml != null)
+ {
+ if (xml.ChildNodes.Count == 1 && xml.ChildNodes[0] is XmlText)
+ {
+ return false;
+ }
+
+ return xml.HasChildNodes;
+ }
+
+ // check for array.
+ Array array = value as Array;
+
+ if (array == null)
+ {
+ Matrix matrix = value as Matrix;
+
+ if (matrix != null)
+ {
+ array = matrix.ToArray();
+ }
+ }
+
+ if (array != null)
+ {
+ return array.Length > 0;
+ }
+
+ // check for list.
+ IList list = value as IList;
+
+ if (list != null)
+ {
+ return list.Count > 0;
+ }
+
+ // check for encodeable object.
+ IEncodeable encodeable = value as IEncodeable;
+
+ if (encodeable != null)
+ {
+ return true;
+ }
+
+ // check for extension object.
+ ExtensionObject extension = value as ExtensionObject;
+
+ if (extension != null)
+ {
+ return IsExpandableType(extension.Body);
+ }
+
+ // check for data value.
+ DataValue datavalue = value as DataValue;
+
+ if (datavalue != null)
+ {
+ return true;
+ }
+
+ // check for event value.
+ EventFieldList eventFields = value as EventFieldList;
+
+ if (eventFields != null)
+ {
+ return true;
+ }
+
+ // must be a simple value.
+ return false;
+ }
+
+ ///
+ /// Formats a value for display in the control.
+ ///
+ private string GetValueText(object value)
+ {
+ // check for null.
+ if (value == null)
+ {
+ return "(null)";
+ }
+
+ // format bytes.
+ byte[] bytes = value as byte[];
+
+ if (bytes != null)
+ {
+ StringBuilder buffer = new StringBuilder();
+
+ for (int ii = 0; ii < bytes.Length; ii++)
+ {
+ if (ii != 0 && ii%16 == 0)
+ {
+ buffer.Append(" ");
+ }
+
+ buffer.AppendFormat("{0:X2} ", bytes[ii]);
+ }
+
+ return buffer.ToString();
+ }
+
+ // format xml element.
+ XmlElement xml = value as XmlElement;
+
+ if (xml != null)
+ {
+ // return the entire element if not expandable.
+ if (!IsExpandableType(xml))
+ {
+ return xml.OuterXml;
+ }
+
+ // show only the start tag.
+ string text = xml.OuterXml;
+
+ int index = text.IndexOf('>');
+
+ if (index != -1)
+ {
+ text = text.Substring(0, index);
+ }
+
+ return text;
+ }
+
+ // format array.
+ Array array = value as Array;
+
+ if (array != null)
+ {
+ if (array.Rank > 1)
+ {
+ int[] lenghts = new int[array.Rank];
+
+ for (int i = 0; i < array.Rank; ++i)
+ {
+ lenghts[i] = array.GetLength(i);
+ }
+
+ return Utils.Format("{1}[{0}]", string.Join(",", lenghts), value.GetType().GetElementType().Name);
+ }
+ else
+ {
+ return Utils.Format("{1}[{0}]", array.Length, value.GetType().GetElementType().Name);
+ }
+ }
+
+ // format list.
+ IList list = value as IList;
+
+ if (list != null)
+ {
+ string type = value.GetType().Name;
+
+ if (type.EndsWith("Collection"))
+ {
+ type = type.Substring(0, type.Length - "Collection".Length);
+ }
+ else
+ {
+ type = "Object";
+ }
+
+ return Utils.Format("{1}[{0}]", list.Count, type);
+ }
+
+ // format encodeable object.
+ IEncodeable encodeable = value as IEncodeable;
+
+ if (encodeable != null)
+ {
+ return encodeable.GetType().Name;
+ }
+
+ // format extension object.
+ ExtensionObject extension = value as ExtensionObject;
+
+ if (extension != null)
+ {
+ return GetValueText(extension.Body);
+ }
+
+ // check for event value.
+ EventFieldList eventFields = value as EventFieldList;
+
+ if (eventFields != null)
+ {
+ if (m_monitoredItem != null)
+ {
+ return String.Format("{0}", m_monitoredItem.GetEventType(eventFields));
+ }
+
+ return eventFields.GetType().Name;
+ }
+
+ // check for data value.
+ DataValue dataValue = value as DataValue;
+
+ if (dataValue != null)
+ {
+ StringBuilder formattedValue = new StringBuilder();
+
+ if (!StatusCode.IsGood(dataValue.StatusCode))
+ {
+ formattedValue.Append("[");
+ formattedValue.AppendFormat("Q:{0}", dataValue.StatusCode);
+ }
+
+ DateTime now = DateTime.UtcNow;
+
+ if ((dataValue != null) &&
+ ((dataValue.ServerTimestamp > now) || (dataValue.SourceTimestamp > now)))
+ {
+ if (formattedValue.ToString().Length > 0)
+ {
+ formattedValue.Append(", ");
+ }
+ else
+ {
+ formattedValue.Append("[");
+ }
+
+ formattedValue.Append("T:future");
+ }
+
+ if (formattedValue.ToString().Length > 0)
+ {
+ formattedValue.Append("] ");
+ }
+
+ formattedValue.AppendFormat("{0}", dataValue.Value);
+ return formattedValue.ToString();
+ }
+
+ // use default formatting.
+ return Utils.Format("{0}", value);
+ }
+
+ ///
+ /// Updates the list with the specified value.
+ ///
+ private void UpdateList(
+ ref int index,
+ ref bool overwrite,
+ object value,
+ object componentValue,
+ object componentId,
+ string name,
+ string type)
+ {
+ // get the list item to update.
+ ListViewItem listitem = GetListItem(index, ref overwrite, name, type);
+ if (componentValue is StatusCode)
+ {
+ listitem.SubItems[1].Text = componentValue.ToString();
+ }
+ else
+ {
+ // update list item.
+ listitem.SubItems[1].Text = GetValueText(componentValue);
+ }
+
+ // move to next item.
+ index++;
+
+ ValueState state = listitem.Tag as ValueState;
+
+ // recursively update sub-values if item is expanded.
+ if (overwrite)
+ {
+ if (state.Expanded && state.Expandable)
+ {
+ m_depth++;
+ ShowValue(ref index, ref overwrite, componentValue);
+ m_depth--;
+ }
+ }
+
+ // update state.
+ state.Expandable = IsExpandableType(componentValue);
+ state.Value = value;
+ state.Component = componentValue;
+ state.ComponentId = componentId;
+ state.ComponentIndex = index;
+
+ if (!state.Expandable)
+ {
+ listitem.ImageKey = CollapseIcon;
+ }
+ }
+
+ ///
+ /// Updates the list with the specified value.
+ ///
+ private void UpdateList(
+ ref int index,
+ ref bool overwrite,
+ object value,
+ object componentValue,
+ object componentId,
+ string name,
+ string type,
+ bool enabled)
+ {
+ // get the list item to update.
+ ListViewItem listitem = GetListItem(index, ref overwrite, name, type);
+
+ if (!enabled)
+ {
+ listitem.ForeColor = Color.LightGray;
+ }
+
+ // update list item.
+ listitem.SubItems[1].Text = GetValueText(componentValue);
+
+ // move to next item.
+ index++;
+
+ ValueState state = listitem.Tag as ValueState;
+
+ // recursively update sub-values if item is expanded.
+ if (overwrite)
+ {
+ if (state.Expanded && state.Expandable)
+ {
+ m_depth++;
+ ShowValue(ref index, ref overwrite, componentValue);
+ m_depth--;
+ }
+ }
+
+ // update state.
+ state.Expandable = IsExpandableType(componentValue);
+ state.Value = value;
+ state.Component = componentValue;
+ state.ComponentId = componentId;
+ state.ComponentIndex = index;
+
+ if (!state.Expandable)
+ {
+ listitem.ImageKey = CollapseIcon;
+ }
+ }
+ ///
+ /// Shows property of an encodeable object in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, IEncodeable value, PropertyInfo property)
+ {
+ // get the name of the property.
+ string name = Utils.GetDataMemberName(property);
+
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the property value.
+ object propertyValue = null;
+
+ MethodInfo[] accessors = property.GetAccessors();
+
+ for (int ii = 0; ii < accessors.Length; ii++)
+ {
+ if (accessors[ii].ReturnType == property.PropertyType)
+ {
+ propertyValue = accessors[ii].Invoke(value, null);
+ break;
+ }
+ }
+
+ if (propertyValue is Variant)
+ {
+ propertyValue = ((Variant)propertyValue).Value;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ propertyValue,
+ property,
+ name,
+ property.PropertyType.Name);
+ }
+
+ ///
+ /// Shows the element of an array in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, Array value, int element)
+ {
+ // get the name of the element.
+ string name = Utils.Format("[{0}]", element);
+
+ // get the element value.
+ object elementValue = null;
+
+ if (value.Rank > 1)
+ {
+ int[] smallArrayDimmensions = new int[value.Rank - 1];
+ int length = 1;
+
+ for (int i = 0; i < value.Rank - 1; ++i)
+ {
+ smallArrayDimmensions[i] = value.GetLength(i + 1);
+ length *= smallArrayDimmensions[i];
+ }
+
+ Array flatArray = Utils.FlattenArray(value);
+ Array flatSmallArray = Array.CreateInstance(value.GetType().GetElementType(), length);
+ Array.Copy(flatArray, element * value.GetLength(1), flatSmallArray, 0, length);
+ Array smallArray = Array.CreateInstance(value.GetType().GetElementType(), smallArrayDimmensions);
+ int[] indexes = new int[smallArrayDimmensions.Length];
+
+ for (int ii = 0; ii < flatSmallArray.Length; ii++)
+ {
+ smallArray.SetValue(flatSmallArray.GetValue(ii), indexes);
+
+ for (int jj = indexes.Length - 1; jj >= 0; jj--)
+ {
+ indexes[jj]++;
+
+ if (indexes[jj] < smallArrayDimmensions[jj])
+ {
+ break;
+ }
+
+ indexes[jj] = 0;
+ }
+ }
+
+ elementValue = smallArray;
+ }
+ else
+ {
+ elementValue = value.GetValue(element);
+ }
+
+ // get the type name.
+ string type = null;
+
+ if (elementValue != null)
+ {
+ type = elementValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ elementValue,
+ element,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows the element of an array in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, Array value, int element, bool enabled)
+ {
+ // get the name of the element.
+ string name = Utils.Format("[{0}]", element);
+
+ // get the element value.
+ object elementValue = value.GetValue(element);
+
+ // get the type name.
+ string type = null;
+
+ if (elementValue != null)
+ {
+ type = elementValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ elementValue,
+ element,
+ name,
+ type,
+ enabled);
+ }
+
+ ///
+ /// Asks for confirmation before expanding a long list.
+ ///
+ private bool PromptOnLongList(int length)
+ {
+ if (length < 256)
+ {
+ return true;
+ }
+
+ DialogResult result = MessageBox.Show("It may take a long time to display the list are you sure you want to continue?", "Warning", MessageBoxButtons.YesNo);
+
+ if (result == DialogResult.Yes)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Shows the element of a list in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, IList value, int element)
+ {
+ // get the name of the element.
+ string name = Utils.Format("[{0}]", element);
+
+ // get the element value.
+ object elementValue = value[element];
+
+ // get the type name.
+ string type = null;
+
+ if (elementValue != null)
+ {
+ type = elementValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ elementValue,
+ element,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows an XML element in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, XmlElement value, int childIndex)
+ {
+ // ignore children that are not elements.
+ XmlElement child = value.ChildNodes[childIndex] as XmlElement;
+
+ if (child == null)
+ {
+ return;
+ }
+
+ // get the name of the element.
+ string name = Utils.Format("{0}", child.Name);
+
+ // get the type name.
+ string type = value.GetType().Name;
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ child,
+ childIndex,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows an event in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, EventFieldList value, int fieldIndex)
+ {
+ // ignore children that are not elements.
+ object field = value.EventFields[fieldIndex].Value;
+
+ if (field == null)
+ {
+ return;
+ }
+
+ // get the name of the element.
+ string name = null;
+
+ if (m_monitoredItem != null)
+ {
+ name = m_monitoredItem.GetFieldName(fieldIndex);
+ }
+
+ // get the type name.
+ string type = value.GetType().Name;
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ field,
+ fieldIndex,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows a byte array in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, byte[] value, int blockStart)
+ {
+ // get the name of the element.
+ string name = Utils.Format("[{0:X4}]", blockStart);
+
+ int bytesLeft = value.Length - blockStart;
+
+ if (bytesLeft > 16)
+ {
+ bytesLeft = 16;
+ }
+
+ // get the element value.
+ byte[] blockValue = new byte[bytesLeft];
+ Array.Copy(value, blockStart, blockValue, 0, bytesLeft);
+
+ // get the type name.
+ string type = value.GetType().Name;
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ blockValue,
+ blockStart,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows a data value in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, DataValue value, int component)
+ {
+ string name = null;
+ object componentValue = null;
+
+ switch (component)
+ {
+ case 0:
+ {
+ name = "Value";
+ componentValue = value.Value;
+
+ ExtensionObject extension = componentValue as ExtensionObject;
+
+ if (extension != null)
+ {
+ componentValue = extension.Body;
+ }
+
+ break;
+ }
+
+ case 1:
+ {
+ name = "StatusCode";
+ componentValue = value.StatusCode;
+ break;
+ }
+
+ case 2:
+ {
+ if (value.SourceTimestamp != DateTime.MinValue)
+ {
+ name = "SourceTimestamp";
+ componentValue = value.SourceTimestamp;
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ if (value.ServerTimestamp != DateTime.MinValue)
+ {
+ name = "ServerTimestamp";
+ componentValue = value.ServerTimestamp;
+ }
+
+ break;
+ }
+ }
+
+ // don't display empty components.
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the type name.
+ string type = "(unknown)";
+
+ if (componentValue != null)
+ {
+ type = componentValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ componentValue,
+ component,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows a node id in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, NodeId value, int component)
+ {
+ string name = null;
+ object componentValue = null;
+
+ switch (component)
+ {
+ case 0:
+ {
+ name = "IdType";
+ componentValue = value.IdType;
+ break;
+ }
+
+ case 1:
+ {
+ name = "Identifier";
+ componentValue = value.Identifier;
+ break;
+ }
+
+ case 2:
+ {
+ name = "NamespaceIndex";
+ componentValue = value.NamespaceIndex;
+ break;
+ }
+ }
+
+ // don't display empty components.
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the type name.
+ string type = "(unknown)";
+
+ if (componentValue != null)
+ {
+ type = componentValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ componentValue,
+ component,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows am expanded node id in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, ExpandedNodeId value, int component)
+ {
+ string name = null;
+ object componentValue = null;
+
+ switch (component)
+ {
+ case 0:
+ {
+ name = "IdType";
+ componentValue = value.IdType;
+ break;
+ }
+
+ case 1:
+ {
+ name = "Identifier";
+ componentValue = value.Identifier;
+ break;
+ }
+
+ case 2:
+ {
+ name = "NamespaceIndex";
+ componentValue = value.NamespaceIndex;
+ break;
+ }
+
+ case 3:
+ {
+ name = "NamespaceUri";
+ componentValue = value.NamespaceUri;
+ break;
+ }
+ }
+
+ // don't display empty components.
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the type name.
+ string type = "(unknown)";
+
+ if (componentValue != null)
+ {
+ type = componentValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ componentValue,
+ component,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows qualified name in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, QualifiedName value, int component)
+ {
+ string name = null;
+ object componentValue = null;
+
+ switch (component)
+ {
+ case 0:
+ {
+ name = "Name";
+ componentValue = value.Name;
+ break;
+ }
+
+ case 1:
+ {
+ name = "NamespaceIndex";
+ componentValue = value.NamespaceIndex;
+ break;
+ }
+ }
+
+ // don't display empty components.
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the type name.
+ string type = "(unknown)";
+
+ if (componentValue != null)
+ {
+ type = componentValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ componentValue,
+ component,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows localized text in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, LocalizedText value, int component)
+ {
+ string name = null;
+ object componentValue = null;
+
+ switch (component)
+ {
+ case 0:
+ {
+ name = "Text";
+ componentValue = value.Text;
+ break;
+ }
+
+ case 1:
+ {
+ name = "Locale";
+ componentValue = value.Locale;
+ break;
+ }
+ }
+
+ // don't display empty components.
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the type name.
+ string type = "(unknown)";
+
+ if (componentValue != null)
+ {
+ type = componentValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ componentValue,
+ component,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows a string in the control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, string value)
+ {
+ string name = "Value";
+ object componentValue = value;
+
+ // don't display empty components.
+ if (name == null)
+ {
+ return;
+ }
+
+ // get the type name.
+ string type = "(unknown)";
+
+ if (componentValue != null)
+ {
+ type = componentValue.GetType().Name;
+ }
+
+ // update the list view.
+ UpdateList(
+ ref index,
+ ref overwrite,
+ value,
+ componentValue,
+ 0,
+ name,
+ type);
+ }
+
+ ///
+ /// Shows a value in control.
+ ///
+ private void ShowValue(ref int index, ref bool overwrite, object value)
+ {
+ if (value == null)
+ {
+ return;
+ }
+
+ // show monitored items.
+ MonitoredItem monitoredItem = value as MonitoredItem;
+
+ if (monitoredItem != null)
+ {
+ m_monitoredItem = monitoredItem;
+ ShowValue(ref index, ref overwrite, monitoredItem.LastValue);
+ return;
+ }
+
+ // show data changes
+ MonitoredItemNotification datachange = value as MonitoredItemNotification;
+
+ if (datachange != null)
+ {
+ ShowValue(ref index, ref overwrite, datachange.Value);
+ return;
+ }
+
+ // show write value with IndexRange
+ WriteValue writevalue = value as WriteValue;
+
+ if (writevalue != null)
+ {
+ // check if the value is an array
+ Array arrayvalue = writevalue.Value.Value as Array;
+
+ if (arrayvalue != null)
+ {
+ NumericRange indexRange;
+ ServiceResult result = NumericRange.Validate(writevalue.IndexRange, out indexRange);
+
+ if (ServiceResult.IsGood(result) && indexRange != NumericRange.Empty)
+ {
+ for (int ii = 0; ii < arrayvalue.Length; ii++)
+ {
+ bool enabled = ((indexRange.Begin <= ii && indexRange.End >= ii) ||
+ (indexRange.End < 0 && indexRange.Begin == ii));
+
+ ShowValue(ref index, ref overwrite, arrayvalue, ii, enabled);
+ }
+
+ return;
+ }
+ }
+ }
+
+ // show events
+ EventFieldList eventFields = value as EventFieldList;
+
+ if (eventFields != null)
+ {
+ for (int ii = 0; ii < eventFields.EventFields.Count; ii++)
+ {
+ ShowValue(ref index, ref overwrite, eventFields, ii);
+ }
+
+ return;
+ }
+
+ // show extension bodies.
+ ExtensionObject extension = value as ExtensionObject;
+
+ if (extension != null)
+ {
+ ShowValue(ref index, ref overwrite, extension.Body);
+ return;
+ }
+
+ // show encodeables.
+ IEncodeable encodeable = value as IEncodeable;
+
+ if (encodeable != null)
+ {
+ PropertyInfo[] properties = encodeable.GetType().GetProperties();
+
+ foreach (PropertyInfo property in properties)
+ {
+ ShowValue(ref index, ref overwrite, encodeable, property);
+ }
+
+ return;
+ }
+
+ // show bytes.
+ byte[] bytes = value as byte[];
+
+ if (bytes != null)
+ {
+ if (!PromptOnLongList(bytes.Length/16))
+ {
+ return;
+ }
+
+ for (int ii = 0; ii < bytes.Length; ii+=16)
+ {
+ ShowValue(ref index, ref overwrite, bytes, ii);
+ }
+
+ return;
+ }
+
+ // show arrays
+ Array array = value as Array;
+
+ if (array == null)
+ {
+ Matrix matrix = value as Matrix;
+
+ if (matrix != null)
+ {
+ array = matrix.ToArray();
+ }
+ }
+
+ if (array != null)
+ {
+ if (!PromptOnLongList(array.GetLength(0)))
+ {
+ return;
+ }
+
+ for (int ii = 0; ii < array.GetLength(0); ii++)
+ {
+ ShowValue(ref index, ref overwrite, array, ii);
+ }
+
+ return;
+ }
+
+ // show lists
+ IList list = value as IList;
+
+ if (list != null)
+ {
+ if (!PromptOnLongList(list.Count))
+ {
+ return;
+ }
+
+ for (int ii = 0; ii < list.Count; ii++)
+ {
+ ShowValue(ref index, ref overwrite, list, ii);
+ }
+
+ return;
+ }
+
+ // show xml elements
+ XmlElement xml = value as XmlElement;
+
+ if (xml != null)
+ {
+ if (!PromptOnLongList(xml.ChildNodes.Count))
+ {
+ return;
+ }
+
+ for (int ii = 0; ii < xml.ChildNodes.Count; ii++)
+ {
+ ShowValue(ref index, ref overwrite, xml, ii);
+ }
+
+ return;
+ }
+
+ // show data value.
+ DataValue datavalue = value as DataValue;
+
+ if (datavalue != null)
+ {
+ ShowValue(ref index, ref overwrite, datavalue, 0);
+ ShowValue(ref index, ref overwrite, datavalue, 1);
+ ShowValue(ref index, ref overwrite, datavalue, 2);
+ ShowValue(ref index, ref overwrite, datavalue, 3);
+ return;
+ }
+
+ // show node id value.
+ NodeId nodeId = value as NodeId;
+
+ if (nodeId != null)
+ {
+ ShowValue(ref index, ref overwrite, nodeId, 0);
+ ShowValue(ref index, ref overwrite, nodeId, 1);
+ ShowValue(ref index, ref overwrite, nodeId, 2);
+ return;
+ }
+
+ // show expanded node id value.
+ ExpandedNodeId expandedNodeId = value as ExpandedNodeId;
+
+ if (expandedNodeId != null)
+ {
+ ShowValue(ref index, ref overwrite, expandedNodeId, 0);
+ ShowValue(ref index, ref overwrite, expandedNodeId, 1);
+ ShowValue(ref index, ref overwrite, expandedNodeId, 2);
+ ShowValue(ref index, ref overwrite, expandedNodeId, 3);
+ return;
+ }
+
+ // show qualified name value.
+ QualifiedName qualifiedName = value as QualifiedName;
+
+ if (qualifiedName != null)
+ {
+ ShowValue(ref index, ref overwrite, qualifiedName, 0);
+ ShowValue(ref index, ref overwrite, qualifiedName, 1);
+ return;
+ }
+
+ // show qualified name value.
+ LocalizedText localizedText = value as LocalizedText;
+
+ if (localizedText != null)
+ {
+ ShowValue(ref index, ref overwrite, localizedText, 0);
+ ShowValue(ref index, ref overwrite, localizedText, 1);
+ return;
+ }
+
+ // show variant.
+ Variant? variant = value as Variant?;
+
+ if (variant != null)
+ {
+ ShowValue(ref index, ref overwrite, variant.Value.Value);
+ return;
+ }
+
+ // show unknown types as strings.
+ ShowValue(ref index, ref overwrite, String.Format("{0}", value));
+ }
+
+ private void ItemsLV_MouseClick(object sender, MouseEventArgs e)
+ {
+ try
+ {
+ if (e.Button != MouseButtons.Left)
+ {
+ return;
+ }
+
+ ListViewItem listItem = ItemsLV.GetItemAt(e.X, e.Y);
+
+ if (listItem == null)
+ {
+ return;
+ }
+
+ ValueState state = listItem.Tag as ValueState;
+
+ if (state == null || !state.Expandable)
+ {
+ return;
+ }
+
+ if (state.Expanded)
+ {
+ HideChildren(listItem);
+ }
+ else
+ {
+ ShowChildren(listItem);
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void UpdatesMI_CheckedChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ /*
+ if (m_monitoredItem != null)
+ {
+ if (UpdatesMI.Checked)
+ {
+ m_monitoredItem.Notification += m_MonitoredItemNotification;
+ }
+ else
+ {
+ m_monitoredItem.Notification -= m_MonitoredItemNotification;
+ }
+ }
+ */
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void RefreshMI_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ /*
+ Clear();
+ ShowValue(m_monitoredItem);
+ */
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ClearMI_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ Clear();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void EditMI_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ if (ItemsLV.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ ValueState state = ItemsLV.SelectedItems[0].Tag as ValueState;
+
+ if (!IsEditableType(state.Component))
+ {
+ return;
+ }
+
+ object value = null;
+ if (state.Component is LocalizedText)
+ {
+ value = new StringValueEditDlg().ShowDialog(state.Component.ToString());
+ if (value != null)
+ {
+ value = new LocalizedText(((LocalizedText)state.Component).Key, ((LocalizedText)state.Component).Locale, value.ToString());
+ }
+ }
+ else
+ {
+ value = new SimpleValueEditDlg().ShowDialog(state.Component, state.Component.GetType());
+ }
+
+ if (value == null)
+ {
+ return;
+ }
+
+ if (state.Value is IEncodeable)
+ {
+ PropertyInfo property = (PropertyInfo)state.ComponentId;
+
+ MethodInfo[] accessors = property.GetAccessors();
+
+ for (int ii = 0; ii < accessors.Length; ii++)
+ {
+ if (accessors[ii].ReturnType == typeof(void))
+ {
+ accessors[ii].Invoke(state.Value, new object[] { value });
+ state.Component = value;
+ break;
+ }
+ }
+ }
+
+ DataValue datavalue = state.Value as DataValue;
+
+ if (datavalue != null)
+ {
+ int component = (int)state.ComponentId;
+
+ switch (component)
+ {
+ case 0: { datavalue.Value = value; break; }
+ }
+ }
+
+ if (state.Value is IList)
+ {
+ int ii = (int)state.ComponentId;
+ ((IList)state.Value)[ii] = value;
+ state.Component = value;
+ }
+
+ m_expanding = false;
+ int index = (int)state.ComponentIndex - 1;
+ int indentCount = ItemsLV.Items[index].IndentCount;
+
+ while (index > 0 && ItemsLV.Items[index - 1].IndentCount == indentCount)
+ {
+ --index;
+ }
+
+ bool overwrite = true;
+ ShowValue(ref index, ref overwrite, state.Value);
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void PopupMenu_Opening(object sender, CancelEventArgs e)
+ {
+ try
+ {
+ EditMI.Enabled = false;
+
+ if (ItemsLV.SelectedItems.Count != 1)
+ {
+ return;
+ }
+
+ EditMI.Enabled = (ItemsLV.SelectedItems[0].ForeColor != Color.LightGray);
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.resx
new file mode 100644
index 00000000..664168a0
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DataListCtrl.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.Designer.cs
new file mode 100644
index 00000000..77369326
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.Designer.cs
@@ -0,0 +1,147 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class DateTimeValueEditDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ValueCTRL = new System.Windows.Forms.DateTimePicker();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 28);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(215, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(136, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ValueCTRL);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Size = new System.Drawing.Size(215, 28);
+ this.MainPN.TabIndex = 1;
+ //
+ // ValueCTRL
+ //
+ this.ValueCTRL.CustomFormat = "yyyy-MM-dd HH:mm:ss";
+ this.ValueCTRL.Format = System.Windows.Forms.DateTimePickerFormat.Custom;
+ this.ValueCTRL.Location = new System.Drawing.Point(4, 5);
+ this.ValueCTRL.MaxDate = new System.DateTime(2100, 12, 21, 0, 0, 0, 0);
+ this.ValueCTRL.MinDate = new System.DateTime(1900, 1, 1, 0, 0, 0, 0);
+ this.ValueCTRL.Name = "ValueCTRL";
+ this.ValueCTRL.Size = new System.Drawing.Size(207, 20);
+ this.ValueCTRL.TabIndex = 0;
+ //
+ // DateTimeValueEditDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(215, 59);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "DateTimeValueEditDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Edit DateTime Value";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.DateTimePicker ValueCTRL;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.cs
new file mode 100644
index 00000000..9b2eb595
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.cs
@@ -0,0 +1,97 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog to edit a date/time value
+ ///
+ public partial class DateTimeValueEditDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DateTimeValueEditDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public bool ShowDialog(ref DateTime value)
+ {
+ if (value < ValueCTRL.MinDate)
+ {
+ ValueCTRL.Value = ValueCTRL.MinDate;
+ }
+ else if (value > ValueCTRL.MaxDate)
+ {
+ ValueCTRL.Value = ValueCTRL.MaxDate;
+ }
+ else
+ {
+ ValueCTRL.Value = value;
+ }
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return false;
+ }
+
+ value = ValueCTRL.Value;
+
+ if (value == ValueCTRL.MinDate)
+ {
+ value = DateTime.MinValue;
+ }
+
+ if (value == ValueCTRL.MaxDate)
+ {
+ value = DateTime.MaxValue;
+ }
+
+ return true;
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/DateTimeValueEditDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.Designer.cs
new file mode 100644
index 00000000..c6cdf993
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.Designer.cs
@@ -0,0 +1,131 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ExceptionDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.BottomPanel = new System.Windows.Forms.Panel();
+ this.OkButton = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ExceptionBrowser = new System.Windows.Forms.WebBrowser();
+ this.BottomPanel.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // BottomPanel
+ //
+ this.BottomPanel.Controls.Add(this.OkButton);
+ this.BottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.BottomPanel.Location = new System.Drawing.Point(0, 433);
+ this.BottomPanel.Name = "BottomPanel";
+ this.BottomPanel.Size = new System.Drawing.Size(770, 37);
+ this.BottomPanel.TabIndex = 0;
+ //
+ // OkButton
+ //
+ this.OkButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
+ this.OkButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.OkButton.Location = new System.Drawing.Point(348, 8);
+ this.OkButton.Name = "OkButton";
+ this.OkButton.Size = new System.Drawing.Size(75, 23);
+ this.OkButton.TabIndex = 0;
+ this.OkButton.Text = "OK";
+ this.OkButton.UseVisualStyleBackColor = true;
+ this.OkButton.Click += new System.EventHandler(this.OkButton_Click);
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ExceptionBrowser);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(3);
+ this.MainPN.Size = new System.Drawing.Size(770, 433);
+ this.MainPN.TabIndex = 1;
+ //
+ // ExceptionBrowser
+ //
+ this.ExceptionBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ExceptionBrowser.Location = new System.Drawing.Point(3, 3);
+ this.ExceptionBrowser.MinimumSize = new System.Drawing.Size(20, 20);
+ this.ExceptionBrowser.Name = "ExceptionBrowser";
+ this.ExceptionBrowser.Size = new System.Drawing.Size(764, 427);
+ this.ExceptionBrowser.TabIndex = 0;
+ //
+ // ExceptionDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(770, 470);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.BottomPanel);
+ this.Name = "ExceptionDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Exception";
+ this.BottomPanel.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel BottomPanel;
+ private System.Windows.Forms.Button OkButton;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.WebBrowser ExceptionBrowser;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.cs
new file mode 100644
index 00000000..b3d17efe
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.cs
@@ -0,0 +1,135 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog that displays an exception trace in an HTML page.
+ ///
+ public partial class ExceptionDlg : Form
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ExceptionDlg()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// Replaces all special characters in the message.
+ ///
+ private string ReplaceSpecialCharacters(string message)
+ {
+ message = message.Replace("&", "&");
+ message = message.Replace("<", "<");
+ message = message.Replace(">", ">");
+ message = message.Replace("\"", """);
+ message = message.Replace("'", "'");
+ message = message.Replace("\r\n", "
");
+
+ return message;
+ }
+
+ ///
+ /// Display the exception in the dialog.
+ ///
+ public void ShowDialog(string caption, Exception e)
+ {
+ Text = caption;
+
+ StringBuilder buffer = new StringBuilder();
+
+ buffer.Append("");
+
+ while (e != null)
+ {
+ string message = e.Message;
+
+ ServiceResultException exception = e as ServiceResultException;
+
+ if (exception != null)
+ {
+ message = exception.ToLongString();
+ }
+
+ message = ReplaceSpecialCharacters(message);
+
+ if (exception != null)
+ {
+ buffer.Append("");
+ buffer.Append("");
+ buffer.Append(message);
+ buffer.Append("");
+ buffer.Append("
");
+ }
+ else
+ {
+ buffer.Append("");
+ buffer.Append(message);
+ buffer.Append("
");
+ }
+
+ message = e.StackTrace;
+
+ if (!String.IsNullOrEmpty(message))
+ {
+ message = ReplaceSpecialCharacters(message);
+
+ buffer.Append("");
+ buffer.Append("");
+ buffer.Append(message);
+ buffer.Append("");
+ buffer.Append("
");
+ }
+
+ e = e.InnerException;
+ }
+
+ buffer.Append("");
+
+ ExceptionBrowser.DocumentText = buffer.ToString();
+
+ ShowDialog();
+ }
+
+ private void OkButton_Click(object sender, EventArgs e)
+ {
+ Close();
+ }
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ExceptionDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.Designer.cs
new file mode 100644
index 00000000..ca55b714
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.Designer.cs
@@ -0,0 +1,82 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class GuiUtils
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GuiUtils));
+ this.ImageList = new System.Windows.Forms.ImageList(this.components);
+ this.SuspendLayout();
+ //
+ // ImageList
+ //
+ ImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImageList.ImageStream")));
+ ImageList.TransparentColor = System.Drawing.Color.Transparent;
+ ImageList.Images.SetKeyName(0, "SimpleItem");
+ //
+ // GuiUtils
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Name = "GuiUtils";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs
new file mode 100644
index 00000000..3fc0d351
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs
@@ -0,0 +1,569 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A class that provide various common utility functions and shared resources.
+ ///
+ public partial class GuiUtils : UserControl
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GuiUtils()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// The list of icon images.
+ ///
+ public System.Windows.Forms.ImageList ImageList;
+
+ ///
+ /// Displays the details of an exception.
+ ///
+ public static void HandleException(string caption, MethodBase method, Exception e)
+ {
+ if (String.IsNullOrEmpty(caption))
+ {
+ caption = method.Name;
+ }
+
+ ExceptionDlg.Show(caption, e);
+ }
+
+ ///
+ /// Defines names for the available 16x16 icons.
+ ///
+ public static class Icons
+ {
+ ///
+ /// An attribute
+ ///
+ public const string Attribute = "SimpleItem";
+
+ ///
+ /// A property
+ ///
+ public const string Property = "Property";
+
+ ///
+ /// A variable
+ ///
+ public const string Variable = "Variable";
+
+ ///
+ /// An object
+ ///
+ public const string Object = "Object";
+
+ ///
+ /// A method
+ ///
+ public const string Method = "Method";
+
+ ///
+ /// A single computer.
+ ///
+ public const string Computer = "Computer";
+
+ ///
+ /// A computer network.
+ ///
+ public const string Network = "Network";
+
+ ///
+ /// A folder.
+ ///
+ public const string Folder = "Folder";
+
+ ///
+ /// A selected folder.
+ ///
+ public const string SelectedFolder = "SelectedFolder";
+
+ ///
+ /// A process or application.
+ ///
+ public const string Process = "Process";
+
+ ///
+ /// A certificate
+ ///
+ public const string Certificate = "Certificate";
+
+ ///
+ /// An invalid certificate
+ ///
+ public const string InvalidCertificate = "InvalidCertificate";
+
+ ///
+ /// A certificate store
+ ///
+ public const string CertificateStore = "CertificateStore";
+
+ ///
+ /// A group of users.
+ ///
+ public const string Users = "Users";
+
+ ///
+ /// A service.
+ ///
+ public const string Service = "Service";
+
+ ///
+ /// A logical drive.
+ ///
+ public const string Drive = "Drive";
+
+ ///
+ /// The computer desktop.
+ ///
+ public const string Desktop = "Desktop";
+
+ ///
+ /// A single user.
+ ///
+ public const string SingleUser = "SingleUser";
+
+ ///
+ /// A group of services.
+ ///
+ public const string ServiceGroup = "ServiceGroup";
+
+ ///
+ /// A group of users.
+ ///
+ public const string UserGroup = "UserGroup";
+
+ ///
+ /// A green check
+ ///
+ public const string GreenCheck = "GreenCheck";
+
+ ///
+ /// A red cross
+ ///
+ public const string RedCross = "RedCross";
+
+ ///
+ /// A users icon with a red cross through it.
+ ///
+ public const string UsersRedCross = "UsersRedCross";
+ }
+
+ ///
+ /// Uses the command line to override the UA TCP implementation specified in the configuration.
+ ///
+ /// The configuration instance that stores the configurable information for a UA application.
+ ///
+ public static void OverrideUaTcpImplementation(ApplicationConfiguration configuration)
+ {
+ // check if UA TCP configuration included.
+ TransportConfiguration transport = null;
+
+ for (int ii = 0; ii < configuration.TransportConfigurations.Count; ii++)
+ {
+ if (configuration.TransportConfigurations[ii].UriScheme == Utils.UriSchemeOpcTcp)
+ {
+ transport = configuration.TransportConfigurations[ii];
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Displays the UA-TCP configuration in the form.
+ ///
+ /// The form to display the UA-TCP configuration.
+ /// The configuration instance that stores the configurable information for a UA application.
+ public static void DisplayUaTcpImplementation(Form form, ApplicationConfiguration configuration)
+ {
+ // check if UA TCP configuration included.
+ TransportConfiguration transport = null;
+
+ for (int ii = 0; ii < configuration.TransportConfigurations.Count; ii++)
+ {
+ if (configuration.TransportConfigurations[ii].UriScheme == Utils.UriSchemeOpcTcp)
+ {
+ transport = configuration.TransportConfigurations[ii];
+ break;
+ }
+ }
+
+ // check if UA TCP implementation explicitly specified.
+ if (transport != null)
+ {
+ string text = form.Text;
+
+ int index = text.LastIndexOf("(UA TCP - ");
+
+ if (index >= 0)
+ {
+ text = text.Substring(0, index);
+ }
+
+ form.Text = Utils.Format("{0} (UA TCP - C#)", text);
+ }
+ }
+
+ ///
+ /// Handles a domain validation error.
+ ///
+ /// The caller's text is used as the caption of the shown to provide details about the error.
+ public static bool HandleDomainCheckError(string caption, ServiceResult serviceResult, X509Certificate2 certificate = null)
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.AppendFormat("Certificate could not be validated!\r\n");
+ buffer.AppendFormat("Validation error(s): \r\n");
+ buffer.AppendFormat("\t{0}\r\n", serviceResult.StatusCode);
+ if (certificate != null)
+ {
+ buffer.AppendFormat("\r\nSubject: {0}\r\n", certificate.Subject);
+ buffer.AppendFormat("Issuer: {0}\r\n", X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer)
+ ? "Self-signed" : certificate.Issuer);
+ buffer.AppendFormat("Valid From: {0}\r\n", certificate.NotBefore);
+ buffer.AppendFormat("Valid To: {0}\r\n", certificate.NotAfter);
+ buffer.AppendFormat("Thumbprint: {0}\r\n\r\n", certificate.Thumbprint);
+ var domains = X509Utils.GetDomainsFromCertficate(certificate);
+ if (domains.Count > 0)
+ {
+ bool comma = false;
+ buffer.AppendFormat("Domains:");
+ foreach (var domain in domains)
+ {
+ if (comma)
+ {
+ buffer.Append(",");
+ }
+ buffer.AppendFormat(" {0}", domain);
+ comma = true;
+ }
+ buffer.AppendLine();
+ }
+ }
+ buffer.Append("This certificate validation error indicates that the hostname used to connect");
+ buffer.Append(" is not listed as a valid hostname in the server certificate.");
+ buffer.Append("\r\n\r\nIgnore error and disable the hostname verification?");
+
+ if (MessageBox.Show(buffer.ToString(), caption, MessageBoxButtons.YesNo) == DialogResult.Yes)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Handles a certificate validation error.
+ ///
+ /// The caller's form is used as the caption of the shown to provide details about the error.
+ /// The validator (not used).
+ /// The instance event arguments provided when a certificate validation error occurs.
+ public static void HandleCertificateValidationError(Form form, CertificateValidator validator, CertificateValidationEventArgs e)
+ {
+ HandleCertificateValidationError(form.Text, validator, e);
+ }
+
+ ///
+ /// Handles a certificate validation error.
+ ///
+ /// The caller's text is used as the caption of the shown to provide details about the error.
+ /// The validator (not used).
+ /// The instance event arguments provided when a certificate validation error occurs.
+ public static void HandleCertificateValidationError(string caption, CertificateValidator validator, CertificateValidationEventArgs e)
+ {
+ StringBuilder buffer = new StringBuilder();
+
+ buffer.Append("Certificate could not be validated!\r\n");
+ buffer.Append("Validation error(s): \r\n");
+ ServiceResult error = e.Error;
+ while (error != null)
+ {
+ buffer.AppendFormat("- {0}\r\n", error.ToString().Split('\r', '\n').FirstOrDefault());
+ error = error.InnerResult;
+ }
+ buffer.AppendFormat("\r\nSubject: {0}\r\n", e.Certificate.Subject);
+ buffer.AppendFormat("Issuer: {0}\r\n", (e.Certificate.Subject == e.Certificate.Issuer) ? "Self-signed" : e.Certificate.Issuer);
+ buffer.AppendFormat("Valid From: {0}\r\n", e.Certificate.NotBefore);
+ buffer.AppendFormat("Valid To: {0}\r\n", e.Certificate.NotAfter);
+ buffer.AppendFormat("Thumbprint: {0}\r\n\r\n", e.Certificate.Thumbprint);
+ buffer.Append("Certificate validation errors may indicate an attempt to intercept any data you send ");
+ buffer.Append("to a server or to allow an untrusted client to connect to your server.");
+ buffer.Append("\r\n\r\nAccept anyway?");
+
+ if (MessageBox.Show(buffer.ToString(), caption, MessageBoxButtons.YesNo) == DialogResult.Yes)
+ {
+ e.AcceptAll = true;
+ }
+ }
+
+ ///
+ /// Returns a default value for the data type.
+ ///
+ public static object GetDefaultValue(NodeId datatypeId, int valueRank)
+ {
+ Type type = TypeInfo.GetSystemType(datatypeId, EncodeableFactory.GlobalFactory);
+
+ if (type == null)
+ {
+ return null;
+ }
+
+ if (valueRank < 0)
+ {
+ if (type == typeof(String))
+ {
+ return System.String.Empty;
+ }
+
+ if (type == typeof(byte[]))
+ {
+ return new byte[0];
+ }
+
+ if (type == typeof(NodeId))
+ {
+ return Opc.Ua.NodeId.Null;
+ }
+
+ if (type == typeof(ExpandedNodeId))
+ {
+ return Opc.Ua.ExpandedNodeId.Null;
+ }
+
+ if (type == typeof(QualifiedName))
+ {
+ return Opc.Ua.QualifiedName.Null;
+ }
+
+ if (type == typeof(LocalizedText))
+ {
+ return Opc.Ua.LocalizedText.Null;
+ }
+
+ if (type == typeof(Guid))
+ {
+ return System.Guid.Empty;
+ }
+
+ if (type == typeof(System.Xml.XmlElement))
+ {
+ System.Xml.XmlDocument document = new System.Xml.XmlDocument();
+ document.InnerXml = "";
+ return document.DocumentElement;
+ }
+
+ return Activator.CreateInstance(type);
+ }
+
+ return Array.CreateInstance(type, new int[valueRank]);
+ }
+
+ ///
+ /// Displays a dialog that allows a use to edit a value.
+ ///
+ public static object EditValue(Session session, object value)
+ {
+ TypeInfo typeInfo = TypeInfo.Construct(value);
+
+ if (typeInfo != null)
+ {
+ return EditValue(session, value, (uint)typeInfo.BuiltInType, typeInfo.ValueRank);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Displays a dialog that allows a use to edit a value.
+ ///
+ public static object EditValue(Session session, object value, NodeId datatypeId, int valueRank)
+ {
+ if (value == null)
+ {
+ value = GetDefaultValue(datatypeId, valueRank);
+ }
+
+ if (valueRank >= 0)
+ {
+ return new ComplexValueEditDlg().ShowDialog(value);
+ }
+
+ BuiltInType builtinType = TypeInfo.GetBuiltInType(datatypeId, session.TypeTree);
+
+ switch (builtinType)
+ {
+ case BuiltInType.Boolean:
+ case BuiltInType.Byte:
+ case BuiltInType.SByte:
+ case BuiltInType.Int16:
+ case BuiltInType.UInt16:
+ case BuiltInType.Int32:
+ case BuiltInType.UInt32:
+ case BuiltInType.Int64:
+ case BuiltInType.UInt64:
+ case BuiltInType.Float:
+ case BuiltInType.Double:
+ case BuiltInType.Enumeration:
+ {
+ return new NumericValueEditDlg().ShowDialog(value, TypeInfo.GetSystemType(builtinType, valueRank));
+ }
+
+ case BuiltInType.Number:
+ {
+ return new NumericValueEditDlg().ShowDialog(value, TypeInfo.GetSystemType(BuiltInType.Double, valueRank));
+ }
+
+ case BuiltInType.Integer:
+ {
+ return new NumericValueEditDlg().ShowDialog(value, TypeInfo.GetSystemType(BuiltInType.Int64, valueRank));
+ }
+
+ case BuiltInType.UInteger:
+ {
+ return new NumericValueEditDlg().ShowDialog(value, TypeInfo.GetSystemType(BuiltInType.UInt64, valueRank));
+ }
+
+ case BuiltInType.NodeId:
+ {
+ return new NodeIdValueEditDlg().ShowDialog(session, (NodeId)value);
+ }
+
+ case BuiltInType.ExpandedNodeId:
+ {
+ return new NodeIdValueEditDlg().ShowDialog(session, (ExpandedNodeId)value);
+ }
+
+ case BuiltInType.DateTime:
+ {
+ DateTime datetime = (DateTime)value;
+
+ if (new DateTimeValueEditDlg().ShowDialog(ref datetime))
+ {
+ return datetime;
+ }
+
+ return null;
+ }
+
+ case BuiltInType.QualifiedName:
+ {
+ QualifiedName qname = (QualifiedName)value;
+
+ string name = new StringValueEditDlg().ShowDialog(qname.Name);
+
+ if (name != null)
+ {
+ return new QualifiedName(name, qname.NamespaceIndex);
+ }
+
+ return null;
+ }
+
+ case BuiltInType.String:
+ {
+ return new StringValueEditDlg().ShowDialog((string)value);
+ }
+
+ case BuiltInType.LocalizedText:
+ {
+ LocalizedText ltext = (LocalizedText)value;
+
+ string text = new StringValueEditDlg().ShowDialog(ltext.Text);
+
+ if (text != null)
+ {
+ return new LocalizedText(ltext.Locale, text);
+ }
+
+ return null;
+ }
+ }
+
+ return new ComplexValueEditDlg().ShowDialog(value);
+ }
+
+ ///
+ /// Returns to display icon for the target of a reference.
+ ///
+ public static string GetTargetIcon(Session session, ReferenceDescription reference)
+ {
+ return GetTargetIcon(session, reference.NodeClass, reference.TypeDefinition);
+ }
+
+ ///
+ /// Returns to display icon for the target of a reference.
+ ///
+ public static string GetTargetIcon(Session session, NodeClass nodeClass, ExpandedNodeId typeDefinitionId)
+ {
+ // make sure the type definition is in the cache.
+ INode typeDefinition = session.NodeCache.Find(typeDefinitionId);
+
+ switch (nodeClass)
+ {
+ case NodeClass.Object:
+ {
+ if (session.TypeTree.IsTypeOf(typeDefinitionId, ObjectTypes.FolderType))
+ {
+ return "Folder";
+ }
+
+ return "Object";
+ }
+
+ case NodeClass.Variable:
+ {
+ if (session.TypeTree.IsTypeOf(typeDefinitionId, VariableTypes.PropertyType))
+ {
+ return "Property";
+ }
+
+ return "Variable";
+ }
+ }
+
+ return nodeClass.ToString();
+ }
+
+ #region Private Methods
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.resx
new file mode 100644
index 00000000..5b2ce242
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.resx
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ False
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADi
+ AgAAAk1TRnQBSQFMAwEBAAEMAQABDAEAARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMA
+ ARADAAEBAQABGAYAAQwSADD/kAAw/5AAMP+QADD/kAAS/wF1AVsBRgFuAVUBQQFqAVABOwFmAUsBNwFj
+ AUgBMwFjAUgBMwFjAUgBMwFjAUgBMwFjAUgBMwP/kAAP/wGFAW0BWgHtAeYB4wG/AacBmgG4AZ8BkAGy
+ AZcBiAGrAZABgAGlAYkBeQGgAYQBcgGbAYABbgGWAXwBaQFjAUgBM5AAAc4BuwGwAbYBnAGNAaQBiwF9
+ Bv8BjgF2AWQB8gHtAeoB7gHmAeIB6QHgAdwB5AHZAdQB3wHSAcsB2gHLAcMB1QHFAbwB0QG+AbQBmgF/
+ AWwBYwFIATOQAAHcAc0BxQHHAbEBpQG2AZwBjgHHAbEBpQGqAY4BfgGXAYABbwH2AfIB8QHyAe0B6gHt
+ AeYB4wHoAeAB3AHkAdkB0wHfAdIBywHaAcwBwwHVAcUBvAGdAYMBcQFjAUgBM5AAAe4B5wHkAdsBzQHG
+ AckBuAGvBv8BoAGKAXoB+QH3AvYB8gHxAfIB7QHqAe0B5wHjAekB4AHcAeQB2QHUAd8B0gHMAdoBzAHD
+ AaIBhwF1AWMBSAEzkAAP/wGpAZQBhAH9AfsB/AH5AvcB9gHzAfAB8gHtAeoB7QHnAeMB6QHgAdwB5AHZ
+ AdQB3wHSAcwBpgGMAXsBZQFKATWQAA//AbIBnQGOA/8C/AH7AfoB+AH3AfYB8gHxAfIB7QHqAe4B5wHj
+ AekB4AHbAeQB2QHUAd8B0gHLAWkBTgE6kAAS/wG2AaEBkwGuAZoBiwGnAZEBgQGfAYkBeQGXAYABbwGP
+ AXcBZQGHAW8BXQF/AWcBUwF4AV8BTAP/kAAw/5AAMP+QADD/kAAw/5AAAUIBTQE+BwABPgMAASgDAAFA
+ AwABEAMAAQEBAAEBBQABgBcAA/+BAAs=
+
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.Designer.cs
new file mode 100644
index 00000000..36713968
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.Designer.cs
@@ -0,0 +1,106 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class NodeIdCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.NodeIdTB = new System.Windows.Forms.TextBox();
+ this.BrowseBTN = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // NodeIdTB
+ //
+ this.NodeIdTB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.NodeIdTB.Location = new System.Drawing.Point(0, 0);
+ this.NodeIdTB.Name = "NodeIdTB";
+ this.NodeIdTB.Size = new System.Drawing.Size(175, 20);
+ this.NodeIdTB.TabIndex = 0;
+ this.NodeIdTB.TextChanged += new System.EventHandler(this.NodeIdTB_TextChanged);
+ //
+ // BrowseBTN
+ //
+ this.BrowseBTN.Dock = System.Windows.Forms.DockStyle.Right;
+ this.BrowseBTN.Location = new System.Drawing.Point(176, 0);
+ this.BrowseBTN.Name = "BrowseBTN";
+ this.BrowseBTN.Size = new System.Drawing.Size(24, 20);
+ this.BrowseBTN.TabIndex = 5;
+ this.BrowseBTN.Text = "...";
+ this.BrowseBTN.UseVisualStyleBackColor = true;
+ this.BrowseBTN.Click += new System.EventHandler(this.BrowseBTN_Click);
+ //
+ // NodeIdCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.BrowseBTN);
+ this.Controls.Add(this.NodeIdTB);
+ this.MaximumSize = new System.Drawing.Size(4096, 20);
+ this.MinimumSize = new System.Drawing.Size(100, 20);
+ this.Name = "NodeIdCtrl";
+ this.Size = new System.Drawing.Size(200, 20);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox NodeIdTB;
+ private System.Windows.Forms.Button BrowseBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.cs
new file mode 100644
index 00000000..83f0c65e
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.cs
@@ -0,0 +1,204 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+using Opc.Ua.Client;
+using Opc.Ua.Client.Controls;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A list of node ids.
+ ///
+ public partial class NodeIdCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public NodeIdCtrl()
+ {
+ InitializeComponent();
+
+ m_rootId = Objects.RootFolder;
+ BrowseBTN.Enabled = false;
+ }
+ #endregion
+
+ #region Event Handlers
+ private Browser m_browser;
+ private NodeId m_rootId;
+ private ReferenceDescription m_reference;
+ private event EventHandler m_IdentifierChanged;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Raised if the node id is changed.
+ ///
+ public event EventHandler IdentifierChanged
+ {
+ add { m_IdentifierChanged += value; }
+ remove { m_IdentifierChanged -= value; }
+ }
+
+ ///
+ /// The browser to used browse for a node id.
+ ///
+ [DefaultValue(null)]
+ public Browser Browser
+ {
+ get
+ {
+ return m_browser;
+ }
+
+ set
+ {
+ m_browser = value;
+ BrowseBTN.Enabled = m_browser != null;
+ }
+ }
+
+ ///
+ /// The root node id to display when browsing.
+ ///
+ [DefaultValue(null)]
+ public NodeId RootId
+ {
+ get
+ {
+ return m_rootId;
+ }
+
+ set
+ {
+ m_rootId = value;
+
+ if (NodeId.IsNull(m_rootId))
+ {
+ m_rootId = Objects.RootFolder;
+ }
+ }
+ }
+
+ ///
+ /// Returns true if the control is empty.
+ ///
+ [DefaultValue(false)]
+ public bool IsEmpty
+ {
+ get
+ {
+ return String.IsNullOrEmpty(NodeIdTB.Text);
+ }
+ }
+
+ ///
+ /// The node identifier specified in the control.
+ ///
+ [DefaultValue(null)]
+ public NodeId Identifier
+ {
+ get
+ {
+ return NodeId.Parse(NodeIdTB.Text);
+ }
+
+ set
+ {
+ NodeIdTB.Text = Utils.Format("{0}", value);
+ }
+ }
+
+ ///
+ /// The reference seleected if the browse feature was used.
+ ///
+ [DefaultValue(null)]
+ public ReferenceDescription Reference
+ {
+ get
+ {
+ return m_reference;
+ }
+
+ set
+ {
+ m_reference = value;
+
+ if (m_reference != null)
+ {
+ NodeIdTB.Text = Utils.Format("{0}", m_reference.NodeId);
+ }
+ }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void BrowseBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ ReferenceDescription reference = new SelectNodeDlg().ShowDialog(m_browser.Session, RootId, null, "", null);
+
+ if (reference != null && reference.NodeId != null)
+ {
+ NodeIdTB.Text = Utils.Format("{0}", reference.NodeId);
+ m_reference = reference;
+
+ if (m_IdentifierChanged != null)
+ {
+ m_IdentifierChanged(this, null);
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void NodeIdTB_TextChanged(object sender, EventArgs e)
+ {
+ if (m_IdentifierChanged != null)
+ {
+ m_IdentifierChanged(this, null);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.Designer.cs
new file mode 100644
index 00000000..ef82502f
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.Designer.cs
@@ -0,0 +1,147 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class NodeIdValueEditDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ValueCTRL = new Opc.Ua.Client.Controls.NodeIdCtrl();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 28);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(297, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(218, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ValueCTRL);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Size = new System.Drawing.Size(297, 28);
+ this.MainPN.TabIndex = 1;
+ //
+ // ValueCTRL
+ //
+ this.ValueCTRL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ValueCTRL.Location = new System.Drawing.Point(4, 4);
+ this.ValueCTRL.MaximumSize = new System.Drawing.Size(4096, 20);
+ this.ValueCTRL.MinimumSize = new System.Drawing.Size(100, 20);
+ this.ValueCTRL.Name = "ValueCTRL";
+ this.ValueCTRL.Size = new System.Drawing.Size(289, 20);
+ this.ValueCTRL.TabIndex = 2;
+ //
+ // NodeIdValueEditDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(297, 59);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "NodeIdValueEditDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Edit NodeId";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private Opc.Ua.Client.Controls.NodeIdCtrl ValueCTRL;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.cs
new file mode 100644
index 00000000..c57e3949
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.cs
@@ -0,0 +1,99 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+using Opc.Ua.Client;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog used to edit a NodeId.
+ ///
+ public partial class NodeIdValueEditDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public NodeIdValueEditDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public NodeId ShowDialog(Session session, NodeId value)
+ {
+ if (session == null) throw new ArgumentNullException("session");
+
+ ValueCTRL.Browser = new Browser(session);
+ ValueCTRL.RootId = Objects.RootFolder;
+ ValueCTRL.Identifier = value;
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return ValueCTRL.Identifier;
+ }
+
+ ///
+ /// Displays the dialog.
+ ///
+ public ExpandedNodeId ShowDialog(Session session, ExpandedNodeId value)
+ {
+ if (session == null) throw new ArgumentNullException("session");
+
+ ValueCTRL.Browser = new Browser(session);
+ ValueCTRL.RootId = Objects.RootFolder;
+ ValueCTRL.Identifier = ExpandedNodeId.ToNodeId(value, session.NamespaceUris);
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return ValueCTRL.Identifier;
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NodeIdValueEditDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.Designer.cs
new file mode 100644
index 00000000..a642b89d
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.Designer.cs
@@ -0,0 +1,148 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class NumericValueEditDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ValueCTRL = new System.Windows.Forms.NumericUpDown();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.ValueCTRL)).BeginInit();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 28);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(215, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(136, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ValueCTRL);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Size = new System.Drawing.Size(215, 28);
+ this.MainPN.TabIndex = 1;
+ //
+ // ValueCTRL
+ //
+ this.ValueCTRL.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ValueCTRL.Location = new System.Drawing.Point(4, 5);
+ this.ValueCTRL.Name = "ValueCTRL";
+ this.ValueCTRL.Size = new System.Drawing.Size(207, 20);
+ this.ValueCTRL.TabIndex = 0;
+ //
+ // NumericValueEditDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(215, 59);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "NumericValueEditDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Edit Numeric Value";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.ValueCTRL)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.NumericUpDown ValueCTRL;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.cs
new file mode 100644
index 00000000..4e8781dd
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.cs
@@ -0,0 +1,164 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog to edit a numeric value.
+ ///
+ public partial class NumericValueEditDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public NumericValueEditDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public object ShowDialog(object value, Type type)
+ {
+ if ((type == null || type == typeof(Variant)) && value != null)
+ {
+ type = value.GetType();
+ }
+
+ if (type == typeof(Variant))
+ {
+ type = typeof(double);
+ }
+
+ SetLimits(type);
+
+ ValueCTRL.Value = Convert.ToDecimal(value);
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return Convert.ChangeType(ValueCTRL.Value, type);
+ }
+ #endregion
+
+ #region Private Methods
+ ///
+ /// Sets the limits according to the data type.
+ ///
+ private void SetLimits(Type type)
+ {
+ if (type == typeof(sbyte))
+ {
+ ValueCTRL.Minimum = SByte.MinValue;
+ ValueCTRL.Maximum = SByte.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(byte))
+ {
+ ValueCTRL.Minimum = Byte.MinValue;
+ ValueCTRL.Maximum = Byte.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(short))
+ {
+ ValueCTRL.Minimum = Int16.MinValue;
+ ValueCTRL.Maximum = Int16.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(ushort))
+ {
+ ValueCTRL.Minimum = UInt16.MinValue;
+ ValueCTRL.Maximum = UInt16.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(int))
+ {
+ ValueCTRL.Minimum = Int32.MinValue;
+ ValueCTRL.Maximum = Int32.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(uint))
+ {
+ ValueCTRL.Minimum = UInt32.MinValue;
+ ValueCTRL.Maximum = UInt32.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(long))
+ {
+ ValueCTRL.Minimum = Int64.MinValue;
+ ValueCTRL.Maximum = Int64.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(ulong))
+ {
+ ValueCTRL.Minimum = UInt64.MinValue;
+ ValueCTRL.Maximum = UInt64.MaxValue;
+ ValueCTRL.DecimalPlaces = 0;
+ }
+
+ if (type == typeof(float))
+ {
+ ValueCTRL.Minimum = Decimal.MinValue;
+ ValueCTRL.Maximum = Decimal.MaxValue;
+ ValueCTRL.DecimalPlaces = 6;
+ }
+
+ if (type == typeof(double))
+ {
+ ValueCTRL.Minimum = Decimal.MinValue;
+ ValueCTRL.Maximum = Decimal.MaxValue;
+ ValueCTRL.DecimalPlaces = 15;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/NumericValueEditDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.Designer.cs
new file mode 100644
index 00000000..e8d54bd0
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.Designer.cs
@@ -0,0 +1,93 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ReferenceTypeCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ReferenceTypesCB = new System.Windows.Forms.ComboBox();
+ this.SuspendLayout();
+ //
+ // ReferenceTypesCB
+ //
+ this.ReferenceTypesCB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ReferenceTypesCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.ReferenceTypesCB.FormattingEnabled = true;
+ this.ReferenceTypesCB.Location = new System.Drawing.Point(0, 0);
+ this.ReferenceTypesCB.Name = "ReferenceTypesCB";
+ this.ReferenceTypesCB.Size = new System.Drawing.Size(200, 21);
+ this.ReferenceTypesCB.TabIndex = 0;
+ this.ReferenceTypesCB.SelectedIndexChanged += new System.EventHandler(this.ReferenceTypesCB_SelectedIndexChanged);
+ //
+ // ReferenceTypeCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.ReferenceTypesCB);
+ this.MaximumSize = new System.Drawing.Size(4096, 21);
+ this.MinimumSize = new System.Drawing.Size(200, 21);
+ this.Name = "ReferenceTypeCtrl";
+ this.Size = new System.Drawing.Size(200, 21);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ComboBox ReferenceTypesCB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.cs
new file mode 100644
index 00000000..d5013f1c
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.cs
@@ -0,0 +1,273 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Displays a drop down list of reference types.
+ ///
+ public partial class ReferenceTypeCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ReferenceTypeCtrl()
+ {
+ InitializeComponent();
+ m_baseTypeId = Opc.Ua.ReferenceTypeIds.References;
+ }
+ #endregion
+
+ #region Private Fields
+ private Session m_session;
+ private NodeId m_baseTypeId;
+ private event EventHandler m_referenceSelectionChanged;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Initializes the control with references starting with the specified based type.
+ ///
+ public void Initialize(Session session, NodeId baseTypeId)
+ {
+ m_session = session;
+ m_baseTypeId = baseTypeId;
+
+ if (NodeId.IsNull(m_baseTypeId))
+ {
+ m_baseTypeId = ReferenceTypeIds.References;
+ }
+
+ ReferenceTypesCB.Items.Clear();
+
+ // recurcively fetch the reference types from the server.
+ if (m_session != null)
+ {
+ AddReferenceTypes(m_baseTypeId, null);
+ }
+ }
+
+ ///
+ /// The currently seleected reference type id.
+ ///
+ public NodeId SelectedTypeId
+ {
+ get
+ {
+ ReferenceTypeChoice choice = ReferenceTypesCB.SelectedItem as ReferenceTypeChoice;
+
+ if (choice == null)
+ {
+ return null;
+ }
+
+ return choice.ReferenceType.NodeId;
+ }
+
+ set
+ {
+ for (int ii = 0; ii < ReferenceTypesCB.Items.Count; ii++)
+ {
+ ReferenceTypeChoice choice = ReferenceTypesCB.Items[ii] as ReferenceTypeChoice;
+
+ if (choice != null && choice.ReferenceType.NodeId == value)
+ {
+ ReferenceTypesCB.SelectedIndex = ii;
+ return;
+ }
+ }
+
+ if (ReferenceTypesCB.Items.Count > 0)
+ {
+ ReferenceTypesCB.SelectedIndex = 0;
+ }
+ }
+ }
+
+ ///
+ /// Raised when the selected reference is changed.
+ ///
+ public event EventHandler ReferenceSelectionChanged
+ {
+ add { m_referenceSelectionChanged += value; }
+ remove { m_referenceSelectionChanged -= value; }
+ }
+
+ #region ReferenceSelectedEventArgs Class
+ ///
+ /// Specifies the nodes that where selected in the control.
+ ///
+ public class ReferenceSelectedEventArgs : EventArgs
+ {
+ ///
+ /// Constructs a new object.
+ ///
+ public ReferenceSelectedEventArgs(NodeId selectedTypeId)
+ {
+ m_referenceTypeId = selectedTypeId;
+ }
+
+ ///
+ /// The reference type that was selected.
+ ///
+ public NodeId ReferenceTypeId
+ {
+ get { return m_referenceTypeId; }
+ }
+
+ private NodeId m_referenceTypeId;
+ }
+ #endregion
+ #endregion
+
+ #region ReferenceTypeChoice Class
+ ///
+ /// A reference type that may be used as a browse filter.
+ ///
+ private class ReferenceTypeChoice
+ {
+ ///
+ /// The text to display in the control.
+ ///
+ public override string ToString()
+ {
+ if (ReferenceType == null)
+ {
+ return "";
+ }
+
+ StringBuilder text = new StringBuilder();
+
+ GetPrefix(text);
+
+ if (text.Length > 0)
+ {
+ text.Append("> ");
+ }
+
+ if (ReferenceType != null)
+ {
+ text.Append(ReferenceType.ToString());
+ }
+
+ return text.ToString();
+ }
+
+ ///
+ /// Adds a prefix for subtypes.
+ ///
+ private void GetPrefix(StringBuilder prefix)
+ {
+ if (SuperType != null)
+ {
+ SuperType.GetPrefix(prefix);
+ prefix.Append("--");
+ }
+ }
+
+ public ReferenceTypeNode ReferenceType;
+ public ReferenceTypeChoice SuperType;
+ }
+ #endregion
+
+ #region Private Methods
+ ///
+ /// Adds the reference types to drop down box.
+ ///
+ private void AddReferenceTypes(ExpandedNodeId referenceTypeId, ReferenceTypeChoice supertype)
+ {
+ if (referenceTypeId == null) throw new ApplicationException("referenceTypeId");
+
+ try
+ {
+ // find reference.
+ ReferenceTypeNode node = m_session.NodeCache.Find(referenceTypeId) as ReferenceTypeNode;
+
+ if (node == null)
+ {
+ return;
+ }
+
+ // add reference to combobox.
+ ReferenceTypeChoice choice = new ReferenceTypeChoice();
+
+ choice.ReferenceType = node;
+ choice.SuperType = supertype;
+
+ ReferenceTypesCB.Items.Add(choice);
+
+ // recursively add subtypes.
+ IList subtypes = m_session.NodeCache.FindReferences(node.NodeId, ReferenceTypeIds.HasSubtype, false, true);
+
+ foreach (INode subtype in subtypes)
+ {
+ AddReferenceTypes(subtype.NodeId, choice);
+ }
+ }
+ catch (Exception e)
+ {
+ Utils.Trace(e, "Ignoring unknown reference type.");
+ return;
+ }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void ReferenceTypesCB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ if (m_referenceSelectionChanged != null)
+ {
+ NodeId referenceTypeId = SelectedTypeId;
+
+ if (referenceTypeId != null)
+ {
+ m_referenceSelectionChanged(this, new ReferenceSelectedEventArgs(referenceTypeId));
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/ReferenceTypeCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.Designer.cs
new file mode 100644
index 00000000..a0ceacf0
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.Designer.cs
@@ -0,0 +1,164 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SimpleValueEditDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ValueLB = new System.Windows.Forms.Label();
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.ValueTB = new System.Windows.Forms.TextBox();
+ this.ButtonsPN.SuspendLayout();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ValueLB
+ //
+ this.ValueLB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ValueLB.AutoSize = true;
+ this.ValueLB.Location = new System.Drawing.Point(4, 9);
+ this.ValueLB.Name = "ValueLB";
+ this.ValueLB.Size = new System.Drawing.Size(34, 13);
+ this.ValueLB.TabIndex = 0;
+ this.ValueLB.Text = "Value";
+ this.ValueLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 33);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(311, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(232, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // panel1
+ //
+ this.panel1.Controls.Add(this.ValueTB);
+ this.panel1.Controls.Add(this.ValueLB);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel1.Location = new System.Drawing.Point(0, 0);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(311, 33);
+ this.panel1.TabIndex = 1;
+ //
+ // ValueTB
+ //
+ this.ValueTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ValueTB.Location = new System.Drawing.Point(44, 7);
+ this.ValueTB.Name = "ValueTB";
+ this.ValueTB.Size = new System.Drawing.Size(263, 20);
+ this.ValueTB.TabIndex = 1;
+ //
+ // SimpleValueEditDlg
+ //
+ this.AcceptButton = this.OkBTN;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.CancelBTN;
+ this.ClientSize = new System.Drawing.Size(311, 64);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.ButtonsPN);
+ this.MinimumSize = new System.Drawing.Size(287, 98);
+ this.Name = "SimpleValueEditDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Edit Value";
+ this.ButtonsPN.ResumeLayout(false);
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label ValueLB;
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.TextBox ValueTB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.cs
new file mode 100644
index 00000000..07b377bb
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.cs
@@ -0,0 +1,148 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using Opc.Ua;
+using Opc.Ua.Client.Controls;
+
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ ///
+ ///
+ public partial class SimpleValueEditDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Default constructor
+ ///
+ public SimpleValueEditDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Private Fields
+ private object m_value;
+ private Type m_type;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public object ShowDialog(object value, Type type)
+ {
+ if (type == null) throw new ArgumentNullException("type");
+
+ m_type = type;
+
+ this.Text = Utils.Format("{0} ({1})", this.Text, type.Name);
+
+ ValueTB.Text = Utils.Format("{0}", value);
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_value;
+ }
+
+ ///
+ /// Returns true if the dialog supports editing the type.
+ ///
+ public static bool IsSimpleType(Type type)
+ {
+ if (type == typeof(bool)) return true;
+ if (type == typeof(sbyte)) return true;
+ if (type == typeof(byte)) return true;
+ if (type == typeof(short)) return true;
+ if (type == typeof(ushort)) return true;
+ if (type == typeof(int)) return true;
+ if (type == typeof(uint)) return true;
+ if (type == typeof(long)) return true;
+ if (type == typeof(ulong)) return true;
+ if (type == typeof(float)) return true;
+ if (type == typeof(double)) return true;
+ if (type == typeof(string)) return true;
+ if (type == typeof(DateTime)) return true;
+ if (type == typeof(Guid)) return true;
+
+ return false;
+ }
+ #endregion
+
+ private object Parse(string text)
+ {
+ if (m_type == typeof(bool)) return Convert.ToBoolean(text);
+ if (m_type == typeof(sbyte)) return Convert.ToSByte(text);
+ if (m_type == typeof(byte)) return Convert.ToByte(text);
+ if (m_type == typeof(short)) return Convert.ToInt16(text);
+ if (m_type == typeof(ushort)) return Convert.ToUInt16(text);
+ if (m_type == typeof(int)) return Convert.ToInt32(text);
+ if (m_type == typeof(uint)) return Convert.ToUInt32(text);
+ if (m_type == typeof(long)) return Convert.ToInt64(text);
+ if (m_type == typeof(ulong)) return Convert.ToUInt64(text);
+ if (m_type == typeof(float)) return Convert.ToSingle(text);
+ if (m_type == typeof(double)) return Convert.ToDouble(text);
+ if (m_type == typeof(string)) return text;
+ if (m_type == typeof(DateTime)) return DateTime.ParseExact(text, "yyyy-MM-dd HH:mm:ss.fff", null);
+ if (m_type == typeof(Guid)) return new Guid(text);
+ if (m_type == typeof(QualifiedName)) return new QualifiedName(text);
+ if (m_type == typeof(LocalizedText)) return new LocalizedText(text);
+
+ throw new ServiceResultException(StatusCodes.BadUnexpectedError, "Cannot convert type.");
+ }
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ m_value = Parse(ValueTB.Text);
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/SimpleValueEditDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.Designer.cs
new file mode 100644
index 00000000..f2cb3a20
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.Designer.cs
@@ -0,0 +1,150 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class StringValueEditDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ValueTB = new System.Windows.Forms.TextBox();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 24);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(252, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(173, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ValueTB);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(3);
+ this.MainPN.Size = new System.Drawing.Size(252, 24);
+ this.MainPN.TabIndex = 1;
+ //
+ // ValueTB
+ //
+ this.ValueTB.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ValueTB.Location = new System.Drawing.Point(3, 3);
+ this.ValueTB.MinimumSize = new System.Drawing.Size(4, 20);
+ this.ValueTB.Multiline = true;
+ this.ValueTB.Name = "ValueTB";
+ this.ValueTB.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ this.ValueTB.Size = new System.Drawing.Size(246, 20);
+ this.ValueTB.TabIndex = 0;
+ this.ValueTB.Text = "Default";
+ //
+ // StringValueEditDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(252, 55);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "StringValueEditDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Edit String Value";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.MainPN.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.TextBox ValueTB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.cs
new file mode 100644
index 00000000..8493705c
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.cs
@@ -0,0 +1,86 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog to edit a string value.
+ ///
+ public partial class StringValueEditDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public StringValueEditDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public string ShowDialog(string value)
+ {
+ ValueTB.Text = value;
+
+ if (value != null)
+ {
+ int length = value.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None).Length;
+
+ if (length > 20)
+ {
+ length = 20;
+ }
+
+ this.Height += (length-1)*16;
+ }
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return ValueTB.Text;
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/Common (OLD)/StringValueEditDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.Designer.cs
new file mode 100644
index 00000000..a878f423
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.Designer.cs
@@ -0,0 +1,89 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SelectCertificateStoreCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.BrowseBTN = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // BrowseBTN
+ //
+ this.BrowseBTN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.BrowseBTN.Location = new System.Drawing.Point(0, 0);
+ this.BrowseBTN.Name = "BrowseBTN";
+ this.BrowseBTN.Size = new System.Drawing.Size(24, 24);
+ this.BrowseBTN.TabIndex = 0;
+ this.BrowseBTN.Text = "...";
+ this.BrowseBTN.UseVisualStyleBackColor = true;
+ this.BrowseBTN.Click += new System.EventHandler(this.BrowseBTN_Click);
+ //
+ // SelectFileCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.BrowseBTN);
+ this.Name = "SelectFileCtrl";
+ this.Size = new System.Drawing.Size(24, 24);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button BrowseBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.cs
new file mode 100644
index 00000000..2ab31ee4
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.cs
@@ -0,0 +1,100 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A control with button that displays a select certificate store dialog.
+ ///
+ public partial class SelectCertificateStoreCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Creates a new instance of the control.
+ ///
+ public SelectCertificateStoreCtrl()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private event EventHandler m_CertificateStoreSelected;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Gets or sets the control that is stores with the current certificate store.
+ ///
+ public Control CertificateStoreControl { get; set; }
+
+ ///
+ /// Raised when a new file is selected.
+ ///
+ public event EventHandler CertificateStoreSelected
+ {
+ add { m_CertificateStoreSelected += value; }
+ remove { m_CertificateStoreSelected -= value; }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void BrowseBTN_Click(object sender, EventArgs e)
+ {
+ CertificateStoreIdentifier store = new CertificateStoreIdentifier();
+ store.StoreType = CertificateStoreIdentifier.DetermineStoreType(CertificateStoreControl.Text);
+ store.StorePath = CertificateStoreControl.Text;
+
+ store = new CertificateStoreDlg().ShowDialog(store);
+
+ if (store == null)
+ {
+ return;
+ }
+
+ CertificateStoreControl.Text = store.StorePath;
+
+ if (m_CertificateStoreSelected != null)
+ {
+ m_CertificateStoreSelected(this, new EventArgs());
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectCertificateStoreCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.Designer.cs
new file mode 100644
index 00000000..69a1ab91
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.Designer.cs
@@ -0,0 +1,89 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SelectFileCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.BrowseBTN = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // BrowseBTN
+ //
+ this.BrowseBTN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.BrowseBTN.Location = new System.Drawing.Point(0, 0);
+ this.BrowseBTN.Name = "BrowseBTN";
+ this.BrowseBTN.Size = new System.Drawing.Size(24, 24);
+ this.BrowseBTN.TabIndex = 0;
+ this.BrowseBTN.Text = "...";
+ this.BrowseBTN.UseVisualStyleBackColor = true;
+ this.BrowseBTN.Click += new System.EventHandler(this.BrowseBTN_Click);
+ //
+ // SelectFileCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.BrowseBTN);
+ this.Name = "SelectFileCtrl";
+ this.Size = new System.Drawing.Size(24, 24);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button BrowseBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.cs
new file mode 100644
index 00000000..da17ce63
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.cs
@@ -0,0 +1,138 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A control with button that displays an open file dialog.
+ ///
+ public partial class SelectFileCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Creates a new instance of the control.
+ ///
+ public SelectFileCtrl()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private event EventHandler m_FileSelected;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Gets or sets the default file extension.
+ ///
+ public string DefaultExt { get; set; }
+
+ ///
+ /// Gets or sets the file filters.
+ ///
+ public string Filter { get; set; }
+
+ ///
+ /// Gets or sets the current directory.
+ ///
+ public string CurrentDirectory { get; set; }
+
+ ///
+ /// Gets or sets the control that is stores with the current file path.
+ ///
+ public Control FilePathControl { get; set; }
+
+ ///
+ /// Raised when a new file is selected.
+ ///
+ public event EventHandler FileSelected
+ {
+ add { m_FileSelected += value; }
+ remove { m_FileSelected -= value; }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void BrowseBTN_Click(object sender, EventArgs e)
+ {
+ if (String.IsNullOrEmpty(Filter))
+ {
+ Filter = "All Files (*.*)|*.*";
+ }
+
+ // set the current directory.
+ if (!String.IsNullOrEmpty(FilePathControl.Text))
+ {
+ FileInfo info = new FileInfo(FilePathControl.Text);
+
+ if (info.Exists)
+ {
+ CurrentDirectory = info.DirectoryName;
+ }
+ }
+
+ // open file dialog.
+ OpenFileDialog dialog = new OpenFileDialog();
+
+ dialog.CheckFileExists = true;
+ dialog.CheckPathExists = true;
+ dialog.DefaultExt = DefaultExt;
+ dialog.Filter = Filter;
+ dialog.Multiselect = false;
+ dialog.ValidateNames = true;
+ dialog.FileName = null;
+ dialog.InitialDirectory = CurrentDirectory;
+ dialog.RestoreDirectory = true;
+
+ if (dialog.ShowDialog() != DialogResult.OK)
+ {
+ return;
+ }
+
+ FilePathControl.Text = dialog.FileName;
+
+ if (m_FileSelected != null)
+ {
+ m_FileSelected(this, new EventArgs());
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectFileCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.Designer.cs
new file mode 100644
index 00000000..2f82ef9e
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.Designer.cs
@@ -0,0 +1,89 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SelectProfileCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.BrowseBTN = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // BrowseBTN
+ //
+ this.BrowseBTN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.BrowseBTN.Location = new System.Drawing.Point(0, 0);
+ this.BrowseBTN.Name = "BrowseBTN";
+ this.BrowseBTN.Size = new System.Drawing.Size(24, 24);
+ this.BrowseBTN.TabIndex = 0;
+ this.BrowseBTN.Text = "...";
+ this.BrowseBTN.UseVisualStyleBackColor = true;
+ this.BrowseBTN.Click += new System.EventHandler(this.BrowseBTN_Click);
+ //
+ // SelectFileCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.BrowseBTN);
+ this.Name = "SelectFileCtrl";
+ this.Size = new System.Drawing.Size(24, 24);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button BrowseBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.cs
new file mode 100644
index 00000000..881abded
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.cs
@@ -0,0 +1,142 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A control with button that displays edit array dialog.
+ ///
+ public partial class SelectProfileCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Creates a new instance of the control.
+ ///
+ public SelectProfileCtrl()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private event EventHandler m_ProfilesChanged;
+ private Opc.Ua.Security.ListOfSecurityProfiles m_profiles;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// The list of available security profiles.
+ ///
+ public Opc.Ua.Security.ListOfSecurityProfiles Profiles
+ {
+ get
+ {
+ return m_profiles;
+ }
+
+ set
+ {
+ if (CurrentProfilesControl != null)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ if (value != null)
+ {
+ for (int ii = 0; ii < value.Count; ii++)
+ {
+ if (value[ii].Enabled)
+ {
+ if (builder.Length > 0)
+ {
+ builder.Append(", ");
+ }
+
+ builder.Append(SecurityPolicies.GetDisplayName(value[ii].ProfileUri));
+ }
+ }
+ }
+
+ CurrentProfilesControl.Text = builder.ToString();
+ }
+
+ m_profiles = value;
+
+ }
+ }
+
+ ///
+ /// Gets or sets the control that is stores with the current file path.
+ ///
+ public Control CurrentProfilesControl { get; set; }
+
+ ///
+ /// Raised when the profiles are changed.
+ ///
+ public event EventHandler ProfilesChanged
+ {
+ add { m_ProfilesChanged += value; }
+ remove { m_ProfilesChanged -= value; }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void BrowseBTN_Click(object sender, EventArgs e)
+ {
+ if (CurrentProfilesControl == null)
+ {
+ return;
+ }
+
+ Opc.Ua.Security.ListOfSecurityProfiles profiles = new SelectProfileDlg().ShowDialog(Profiles, null);
+
+ if (profiles == null)
+ {
+ return;
+ }
+
+ Profiles = profiles;
+
+ if (m_ProfilesChanged != null)
+ {
+ m_ProfilesChanged(this, e);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.Designer.cs
new file mode 100644
index 00000000..22cd50d1
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.Designer.cs
@@ -0,0 +1,148 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SelectProfileDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.BottomPN = new System.Windows.Forms.Panel();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ProfilesLV = new System.Windows.Forms.CheckedListBox();
+ this.BottomPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(277, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(3, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // BottomPN
+ //
+ this.BottomPN.Controls.Add(this.OkBTN);
+ this.BottomPN.Controls.Add(this.CancelBTN);
+ this.BottomPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.BottomPN.Location = new System.Drawing.Point(0, 100);
+ this.BottomPN.Name = "BottomPN";
+ this.BottomPN.Size = new System.Drawing.Size(355, 30);
+ this.BottomPN.TabIndex = 0;
+ //
+ // MainPN
+ //
+ this.MainPN.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+ this.MainPN.Controls.Add(this.ProfilesLV);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(3);
+ this.MainPN.Size = new System.Drawing.Size(355, 100);
+ this.MainPN.TabIndex = 1;
+ //
+ // ProfilesLV
+ //
+ this.ProfilesLV.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ProfilesLV.FormattingEnabled = true;
+ this.ProfilesLV.Location = new System.Drawing.Point(3, 3);
+ this.ProfilesLV.Name = "ProfilesLV";
+ this.ProfilesLV.Size = new System.Drawing.Size(349, 94);
+ this.ProfilesLV.TabIndex = 0;
+ //
+ // SelectProfileDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.CancelBTN;
+ this.ClientSize = new System.Drawing.Size(355, 130);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.BottomPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "SelectProfileDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Select Security Profiles";
+ this.BottomPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Panel BottomPN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.CheckedListBox ProfilesLV;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.cs
new file mode 100644
index 00000000..a9059549
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.cs
@@ -0,0 +1,102 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using System.Drawing;
+using System.Text;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Data;
+using Opc.Ua;
+using Opc.Ua.Client;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Prompts the user to edit a value.
+ ///
+ public partial class SelectProfileDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Creates an empty form.
+ ///
+ public SelectProfileDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Private Fields
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Prompts the user to edit an array value.
+ ///
+ public Opc.Ua.Security.ListOfSecurityProfiles ShowDialog(Opc.Ua.Security.ListOfSecurityProfiles profiles, string caption)
+ {
+ if (caption != null)
+ {
+ this.Text = caption;
+ }
+
+ ProfilesLV.Items.Clear();
+
+ if (profiles != null)
+ {
+ for (int ii = 0; ii < profiles.Count; ii++)
+ {
+ ProfilesLV.Items.Add(profiles[ii].ProfileUri, profiles[ii].Enabled);
+ }
+ }
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ Opc.Ua.Security.ListOfSecurityProfiles results = new Opc.Ua.Security.ListOfSecurityProfiles();
+
+ for (int ii = 0; ii < ProfilesLV.Items.Count; ii++)
+ {
+ Opc.Ua.Security.SecurityProfile profile = new Opc.Ua.Security.SecurityProfile();
+ profile.ProfileUri = ProfilesLV.Items[ii] as string;
+ profile.Enabled = ProfilesLV.CheckedIndices.Contains(ii);
+ results.Add(profile);
+ }
+
+ return results;
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectProfileDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.Designer.cs
new file mode 100644
index 00000000..606b2c8d
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.Designer.cs
@@ -0,0 +1,89 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SelectUrlsCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.BrowseBTN = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // BrowseBTN
+ //
+ this.BrowseBTN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.BrowseBTN.Location = new System.Drawing.Point(0, 0);
+ this.BrowseBTN.Name = "BrowseBTN";
+ this.BrowseBTN.Size = new System.Drawing.Size(24, 24);
+ this.BrowseBTN.TabIndex = 0;
+ this.BrowseBTN.Text = "...";
+ this.BrowseBTN.UseVisualStyleBackColor = true;
+ this.BrowseBTN.Click += new System.EventHandler(this.BrowseBTN_Click);
+ //
+ // SelectFileCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.BrowseBTN);
+ this.Name = "SelectFileCtrl";
+ this.Size = new System.Drawing.Size(24, 24);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button BrowseBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.cs
new file mode 100644
index 00000000..fdbdc268
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.cs
@@ -0,0 +1,168 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.IO;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A control with button that displays edit array dialog.
+ ///
+ public partial class SelectUrlsCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Creates a new instance of the control.
+ ///
+ public SelectUrlsCtrl()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private event EventHandler m_UrlsChanged;
+ private List m_urls;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// The list of urls.
+ ///
+ public List Urls
+ {
+ get
+ {
+ return m_urls;
+ }
+
+ set
+ {
+ if (CurrentUrlsControl != null)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ if (value != null)
+ {
+ for (int ii = 0; ii < value.Count; ii++)
+ {
+ if (builder.Length > 0)
+ {
+ builder.Append(", ");
+ }
+
+ builder.Append(value[ii].Scheme);
+
+ if (value[ii].Port > 0)
+ {
+ builder.Append(":");
+ builder.Append(value[ii].Port);
+ }
+ }
+ }
+
+ CurrentUrlsControl.Text = builder.ToString();
+ }
+
+ m_urls = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the control that is stores with the current file path.
+ ///
+ public Control CurrentUrlsControl { get; set; }
+
+ ///
+ /// Raised when the profiles are changed.
+ ///
+ public event EventHandler UrlsChanged
+ {
+ add { m_UrlsChanged += value; }
+ remove { m_UrlsChanged -= value; }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void BrowseBTN_Click(object sender, EventArgs e)
+ {
+ if (CurrentUrlsControl == null)
+ {
+ return;
+ }
+
+ string[] strings = null;
+
+ if (m_urls != null)
+ {
+ strings = new string[m_urls.Count];
+
+ for (int ii = 0; ii < m_urls.Count; ii++)
+ {
+ strings[ii] = m_urls[ii].ToString();
+ }
+ }
+
+ strings = new EditArrayDlg().ShowDialog(strings, BuiltInType.String, false, null) as string[];
+
+ if (strings == null)
+ {
+ return;
+ }
+
+ List urls = new List();
+
+ for (int ii = 0; ii < strings.Length; ii++)
+ {
+ Uri url = Utils.ParseUri(strings[ii]);
+
+ if (url != null)
+ {
+ urls.Add(url);
+ }
+ }
+
+ Urls = urls;
+
+ if (m_UrlsChanged != null)
+ {
+ m_UrlsChanged(this, e);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/SelectUrlsCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.Designer.cs
new file mode 100644
index 00000000..6a8da149
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.Designer.cs
@@ -0,0 +1,194 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class UserNamePasswordDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.TableLayoutPanel();
+ this.PasswordLB = new System.Windows.Forms.Label();
+ this.UserNameLB = new System.Windows.Forms.Label();
+ this.UserNameTB = new System.Windows.Forms.TextBox();
+ this.PasswordTB = new System.Windows.Forms.TextBox();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 53);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(247, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(168, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.ColumnCount = 2;
+ this.MainPN.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.MainPN.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.MainPN.Controls.Add(this.PasswordLB, 0, 1);
+ this.MainPN.Controls.Add(this.UserNameLB, 0, 0);
+ this.MainPN.Controls.Add(this.UserNameTB, 1, 0);
+ this.MainPN.Controls.Add(this.PasswordTB, 1, 1);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.RowCount = 3;
+ this.MainPN.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.MainPN.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.MainPN.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.MainPN.Size = new System.Drawing.Size(247, 53);
+ this.MainPN.TabIndex = 1;
+ //
+ // PasswordLB
+ //
+ this.PasswordLB.AutoSize = true;
+ this.PasswordLB.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.PasswordLB.Location = new System.Drawing.Point(3, 26);
+ this.PasswordLB.Name = "PasswordLB";
+ this.PasswordLB.Size = new System.Drawing.Size(60, 26);
+ this.PasswordLB.TabIndex = 2;
+ this.PasswordLB.Text = "Password";
+ this.PasswordLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // UserNameLB
+ //
+ this.UserNameLB.AutoSize = true;
+ this.UserNameLB.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.UserNameLB.Location = new System.Drawing.Point(3, 0);
+ this.UserNameLB.Name = "UserNameLB";
+ this.UserNameLB.Size = new System.Drawing.Size(60, 26);
+ this.UserNameLB.TabIndex = 0;
+ this.UserNameLB.Text = "User Name";
+ this.UserNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // UserNameTB
+ //
+ this.UserNameTB.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.UserNameTB.Location = new System.Drawing.Point(69, 3);
+ this.UserNameTB.Name = "UserNameTB";
+ this.UserNameTB.Size = new System.Drawing.Size(175, 20);
+ this.UserNameTB.TabIndex = 1;
+ //
+ // PasswordTB
+ //
+ this.PasswordTB.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.PasswordTB.Location = new System.Drawing.Point(69, 29);
+ this.PasswordTB.Name = "PasswordTB";
+ this.PasswordTB.PasswordChar = '*';
+ this.PasswordTB.Size = new System.Drawing.Size(175, 20);
+ this.PasswordTB.TabIndex = 3;
+ //
+ // UserNamePasswordDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoSize = true;
+ this.CancelButton = this.CancelBTN;
+ this.ClientSize = new System.Drawing.Size(247, 84);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.MaximumSize = new System.Drawing.Size(2048, 2048);
+ this.MinimumSize = new System.Drawing.Size(200, 50);
+ this.Name = "UserNamePasswordDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Enter User Name";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.MainPN.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.TableLayoutPanel MainPN;
+ private System.Windows.Forms.Label PasswordLB;
+ private System.Windows.Forms.Label UserNameLB;
+ private System.Windows.Forms.TextBox UserNameTB;
+ private System.Windows.Forms.TextBox PasswordTB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.cs
new file mode 100644
index 00000000..29404547
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.cs
@@ -0,0 +1,83 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Prompts the user to enter a user name/password.
+ ///
+ public partial class UserNamePasswordDlg : Form
+ {
+ ///
+ /// Contructs the object.
+ ///
+ public UserNamePasswordDlg()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// Displays the dialog.
+ ///
+ public UserIdentity ShowDialog(IUserIdentity identity, string caption)
+ {
+ if (!String.IsNullOrEmpty(caption))
+ {
+ this.Text = caption;
+ }
+
+ if (identity != null)
+ {
+ UserNameIdentityToken token = identity.GetIdentityToken() as UserNameIdentityToken;
+
+ if (token != null)
+ {
+ UserNameTB.Text = token.UserName;
+ PasswordTB.Text = token.DecryptedPassword;
+ }
+ }
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return new UserIdentity(UserNameTB.Text, PasswordTB.Text);
+ }
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/UserNamePasswordDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.Designer.cs
new file mode 100644
index 00000000..6932e655
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.Designer.cs
@@ -0,0 +1,416 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ViewCertificateDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.ExportBTN = new System.Windows.Forms.Button();
+ this.DetailsBTN = new System.Windows.Forms.Button();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.ApplicationNameLB = new System.Windows.Forms.Label();
+ this.ApplicationNameTB = new System.Windows.Forms.TextBox();
+ this.ApplicationUriLB = new System.Windows.Forms.Label();
+ this.ApplicationUriTB = new System.Windows.Forms.TextBox();
+ this.SubjectNameLB = new System.Windows.Forms.Label();
+ this.SubjectNameTB = new System.Windows.Forms.TextBox();
+ this.DomainsLB = new System.Windows.Forms.Label();
+ this.DomainsTB = new System.Windows.Forms.TextBox();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ValidToTB = new System.Windows.Forms.TextBox();
+ this.ValidToLB = new System.Windows.Forms.Label();
+ this.ValidFromTB = new System.Windows.Forms.TextBox();
+ this.ValidFromLB = new System.Windows.Forms.Label();
+ this.ThumbprintTB = new System.Windows.Forms.TextBox();
+ this.ThumbprintLB = new System.Windows.Forms.Label();
+ this.IssuerNameTB = new System.Windows.Forms.TextBox();
+ this.IssuerNameLB = new System.Windows.Forms.Label();
+ this.OrganizationTB = new System.Windows.Forms.TextBox();
+ this.OrganizationLB = new System.Windows.Forms.Label();
+ this.CertificateStoreCTRL = new Opc.Ua.Client.Controls.CertificateStoreCtrl();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.ExportBTN);
+ this.ButtonsPN.Controls.Add(this.DetailsBTN);
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 291);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(708, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // ExportBTN
+ //
+ this.ExportBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.ExportBTN.Location = new System.Drawing.Point(166, 4);
+ this.ExportBTN.Name = "ExportBTN";
+ this.ExportBTN.Size = new System.Drawing.Size(75, 23);
+ this.ExportBTN.TabIndex = 3;
+ this.ExportBTN.Text = "Export...";
+ this.ExportBTN.UseVisualStyleBackColor = true;
+ this.ExportBTN.Click += new System.EventHandler(this.ExportBTN_Click);
+ //
+ // DetailsBTN
+ //
+ this.DetailsBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.DetailsBTN.Location = new System.Drawing.Point(85, 4);
+ this.DetailsBTN.Name = "DetailsBTN";
+ this.DetailsBTN.Size = new System.Drawing.Size(75, 23);
+ this.DetailsBTN.TabIndex = 2;
+ this.DetailsBTN.Text = "Details...";
+ this.DetailsBTN.UseVisualStyleBackColor = true;
+ this.DetailsBTN.Click += new System.EventHandler(this.DetailsBTN_Click);
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(629, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // ApplicationNameLB
+ //
+ this.ApplicationNameLB.AutoSize = true;
+ this.ApplicationNameLB.Location = new System.Drawing.Point(5, 63);
+ this.ApplicationNameLB.Name = "ApplicationNameLB";
+ this.ApplicationNameLB.Size = new System.Drawing.Size(90, 13);
+ this.ApplicationNameLB.TabIndex = 1;
+ this.ApplicationNameLB.Text = "Application Name";
+ this.ApplicationNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ApplicationNameTB
+ //
+ this.ApplicationNameTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ApplicationNameTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ApplicationNameTB.Location = new System.Drawing.Point(96, 60);
+ this.ApplicationNameTB.Name = "ApplicationNameTB";
+ this.ApplicationNameTB.ReadOnly = true;
+ this.ApplicationNameTB.Size = new System.Drawing.Size(608, 20);
+ this.ApplicationNameTB.TabIndex = 2;
+ //
+ // ApplicationUriLB
+ //
+ this.ApplicationUriLB.AutoSize = true;
+ this.ApplicationUriLB.Location = new System.Drawing.Point(5, 115);
+ this.ApplicationUriLB.Name = "ApplicationUriLB";
+ this.ApplicationUriLB.Size = new System.Drawing.Size(81, 13);
+ this.ApplicationUriLB.TabIndex = 5;
+ this.ApplicationUriLB.Text = "Application URI";
+ this.ApplicationUriLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ApplicationUriTB
+ //
+ this.ApplicationUriTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ApplicationUriTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ApplicationUriTB.Location = new System.Drawing.Point(96, 112);
+ this.ApplicationUriTB.Name = "ApplicationUriTB";
+ this.ApplicationUriTB.ReadOnly = true;
+ this.ApplicationUriTB.Size = new System.Drawing.Size(608, 20);
+ this.ApplicationUriTB.TabIndex = 6;
+ //
+ // SubjectNameLB
+ //
+ this.SubjectNameLB.AutoSize = true;
+ this.SubjectNameLB.Location = new System.Drawing.Point(5, 167);
+ this.SubjectNameLB.Name = "SubjectNameLB";
+ this.SubjectNameLB.Size = new System.Drawing.Size(74, 13);
+ this.SubjectNameLB.TabIndex = 9;
+ this.SubjectNameLB.Text = "Subject Name";
+ this.SubjectNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // SubjectNameTB
+ //
+ this.SubjectNameTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.SubjectNameTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.SubjectNameTB.Location = new System.Drawing.Point(96, 164);
+ this.SubjectNameTB.Name = "SubjectNameTB";
+ this.SubjectNameTB.ReadOnly = true;
+ this.SubjectNameTB.Size = new System.Drawing.Size(608, 20);
+ this.SubjectNameTB.TabIndex = 10;
+ //
+ // DomainsLB
+ //
+ this.DomainsLB.AutoSize = true;
+ this.DomainsLB.Location = new System.Drawing.Point(5, 141);
+ this.DomainsLB.Name = "DomainsLB";
+ this.DomainsLB.Size = new System.Drawing.Size(48, 13);
+ this.DomainsLB.TabIndex = 7;
+ this.DomainsLB.Text = "Domains";
+ this.DomainsLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // DomainsTB
+ //
+ this.DomainsTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.DomainsTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.DomainsTB.Location = new System.Drawing.Point(96, 138);
+ this.DomainsTB.Name = "DomainsTB";
+ this.DomainsTB.ReadOnly = true;
+ this.DomainsTB.Size = new System.Drawing.Size(608, 20);
+ this.DomainsTB.TabIndex = 8;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ValidToTB);
+ this.MainPN.Controls.Add(this.ValidToLB);
+ this.MainPN.Controls.Add(this.ValidFromTB);
+ this.MainPN.Controls.Add(this.ValidFromLB);
+ this.MainPN.Controls.Add(this.ThumbprintTB);
+ this.MainPN.Controls.Add(this.ThumbprintLB);
+ this.MainPN.Controls.Add(this.IssuerNameTB);
+ this.MainPN.Controls.Add(this.IssuerNameLB);
+ this.MainPN.Controls.Add(this.OrganizationTB);
+ this.MainPN.Controls.Add(this.OrganizationLB);
+ this.MainPN.Controls.Add(this.CertificateStoreCTRL);
+ this.MainPN.Controls.Add(this.DomainsTB);
+ this.MainPN.Controls.Add(this.DomainsLB);
+ this.MainPN.Controls.Add(this.SubjectNameTB);
+ this.MainPN.Controls.Add(this.SubjectNameLB);
+ this.MainPN.Controls.Add(this.ApplicationUriTB);
+ this.MainPN.Controls.Add(this.ApplicationUriLB);
+ this.MainPN.Controls.Add(this.ApplicationNameTB);
+ this.MainPN.Controls.Add(this.ApplicationNameLB);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Size = new System.Drawing.Size(708, 291);
+ this.MainPN.TabIndex = 1;
+ //
+ // ValidToTB
+ //
+ this.ValidToTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ValidToTB.Location = new System.Drawing.Point(96, 242);
+ this.ValidToTB.Name = "ValidToTB";
+ this.ValidToTB.ReadOnly = true;
+ this.ValidToTB.Size = new System.Drawing.Size(156, 20);
+ this.ValidToTB.TabIndex = 16;
+ //
+ // ValidToLB
+ //
+ this.ValidToLB.AutoSize = true;
+ this.ValidToLB.Location = new System.Drawing.Point(5, 245);
+ this.ValidToLB.Name = "ValidToLB";
+ this.ValidToLB.Size = new System.Drawing.Size(46, 13);
+ this.ValidToLB.TabIndex = 15;
+ this.ValidToLB.Text = "Valid To";
+ this.ValidToLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ValidFromTB
+ //
+ this.ValidFromTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ValidFromTB.Location = new System.Drawing.Point(96, 216);
+ this.ValidFromTB.Name = "ValidFromTB";
+ this.ValidFromTB.ReadOnly = true;
+ this.ValidFromTB.Size = new System.Drawing.Size(156, 20);
+ this.ValidFromTB.TabIndex = 14;
+ //
+ // ValidFromLB
+ //
+ this.ValidFromLB.AutoSize = true;
+ this.ValidFromLB.Location = new System.Drawing.Point(5, 219);
+ this.ValidFromLB.Name = "ValidFromLB";
+ this.ValidFromLB.Size = new System.Drawing.Size(56, 13);
+ this.ValidFromLB.TabIndex = 13;
+ this.ValidFromLB.Text = "Valid From";
+ this.ValidFromLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ThumbprintTB
+ //
+ this.ThumbprintTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ThumbprintTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ThumbprintTB.Location = new System.Drawing.Point(96, 268);
+ this.ThumbprintTB.Name = "ThumbprintTB";
+ this.ThumbprintTB.ReadOnly = true;
+ this.ThumbprintTB.Size = new System.Drawing.Size(609, 20);
+ this.ThumbprintTB.TabIndex = 18;
+ //
+ // ThumbprintLB
+ //
+ this.ThumbprintLB.AutoSize = true;
+ this.ThumbprintLB.Location = new System.Drawing.Point(5, 271);
+ this.ThumbprintLB.Name = "ThumbprintLB";
+ this.ThumbprintLB.Size = new System.Drawing.Size(60, 13);
+ this.ThumbprintLB.TabIndex = 17;
+ this.ThumbprintLB.Text = "Thumbprint";
+ this.ThumbprintLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // IssuerNameTB
+ //
+ this.IssuerNameTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.IssuerNameTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.IssuerNameTB.Location = new System.Drawing.Point(96, 190);
+ this.IssuerNameTB.Name = "IssuerNameTB";
+ this.IssuerNameTB.ReadOnly = true;
+ this.IssuerNameTB.Size = new System.Drawing.Size(608, 20);
+ this.IssuerNameTB.TabIndex = 12;
+ //
+ // IssuerNameLB
+ //
+ this.IssuerNameLB.AutoSize = true;
+ this.IssuerNameLB.Location = new System.Drawing.Point(5, 193);
+ this.IssuerNameLB.Name = "IssuerNameLB";
+ this.IssuerNameLB.Size = new System.Drawing.Size(66, 13);
+ this.IssuerNameLB.TabIndex = 11;
+ this.IssuerNameLB.Text = "Issuer Name";
+ this.IssuerNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // OrganizationTB
+ //
+ this.OrganizationTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.OrganizationTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.OrganizationTB.Location = new System.Drawing.Point(96, 86);
+ this.OrganizationTB.Name = "OrganizationTB";
+ this.OrganizationTB.ReadOnly = true;
+ this.OrganizationTB.Size = new System.Drawing.Size(608, 20);
+ this.OrganizationTB.TabIndex = 4;
+ //
+ // OrganizationLB
+ //
+ this.OrganizationLB.AutoSize = true;
+ this.OrganizationLB.Location = new System.Drawing.Point(5, 89);
+ this.OrganizationLB.Name = "OrganizationLB";
+ this.OrganizationLB.Size = new System.Drawing.Size(66, 13);
+ this.OrganizationLB.TabIndex = 3;
+ this.OrganizationLB.Text = "Organization";
+ this.OrganizationLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // CertificateStoreCTRL
+ //
+ this.CertificateStoreCTRL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.CertificateStoreCTRL.LabelWidth = 91;
+ this.CertificateStoreCTRL.Location = new System.Drawing.Point(4, 6);
+ this.CertificateStoreCTRL.MinimumSize = new System.Drawing.Size(300, 51);
+ this.CertificateStoreCTRL.Name = "CertificateStoreCTRL";
+ this.CertificateStoreCTRL.Size = new System.Drawing.Size(699, 51);
+ this.CertificateStoreCTRL.StorePath = "X:\\OPC\\Source\\UA311\\Source\\Utilities\\CertificateGenerator";
+ this.CertificateStoreCTRL.TabIndex = 0;
+ //
+ // ViewCertificateDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(708, 322);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "ViewCertificateDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "View Certificate";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.MainPN.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Label ApplicationNameLB;
+ private System.Windows.Forms.TextBox ApplicationNameTB;
+ private System.Windows.Forms.Label ApplicationUriLB;
+ private System.Windows.Forms.TextBox ApplicationUriTB;
+ private System.Windows.Forms.Label SubjectNameLB;
+ private System.Windows.Forms.TextBox SubjectNameTB;
+ private System.Windows.Forms.Label DomainsLB;
+ private System.Windows.Forms.TextBox DomainsTB;
+ private System.Windows.Forms.Panel MainPN;
+ private CertificateStoreCtrl CertificateStoreCTRL;
+ private System.Windows.Forms.TextBox OrganizationTB;
+ private System.Windows.Forms.Label OrganizationLB;
+ private System.Windows.Forms.Label ValidFromLB;
+ private System.Windows.Forms.TextBox ThumbprintTB;
+ private System.Windows.Forms.Label ThumbprintLB;
+ private System.Windows.Forms.TextBox IssuerNameTB;
+ private System.Windows.Forms.Label IssuerNameLB;
+ private System.Windows.Forms.TextBox ValidToTB;
+ private System.Windows.Forms.Label ValidToLB;
+ private System.Windows.Forms.TextBox ValidFromTB;
+ private System.Windows.Forms.Button DetailsBTN;
+ private System.Windows.Forms.Button ExportBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.cs
new file mode 100644
index 00000000..a39c19c9
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.cs
@@ -0,0 +1,286 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Text;
+using System.IO;
+using System.Security.Cryptography.X509Certificates;
+using System.Windows.Forms;
+using System.Threading.Tasks;
+using Opc.Ua.Security.Certificates;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Prompts the user to specify a new access rule for a file.
+ ///
+ public partial class ViewCertificateDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes the dialog.
+ ///
+ public ViewCertificateDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Private Fields
+ private string m_currentDirectory;
+ private CertificateIdentifier m_certificate;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public async Task ShowDialog(CertificateIdentifier certificate)
+ {
+ m_certificate = certificate;
+
+ CertificateStoreCTRL.StoreType = null;
+ CertificateStoreCTRL.StorePath = null;
+ CertificateStoreCTRL.ReadOnly = true;
+ ApplicationNameTB.Text = null;
+ ApplicationUriTB.Text = null;
+ OrganizationTB.Text = null;
+ DomainsTB.Text = System.Net.Dns.GetHostName();
+ SubjectNameTB.Text = null;
+ IssuerNameTB.Text = null;
+ ValidFromTB.Text = null;
+ ValidToTB.Text = null;
+ ThumbprintTB.Text = null;
+
+ if (certificate != null)
+ {
+ CertificateStoreCTRL.StoreType = certificate.StoreType;
+ CertificateStoreCTRL.StorePath = certificate.StorePath;
+ SubjectNameTB.Text = certificate.SubjectName;
+ ThumbprintTB.Text = certificate.Thumbprint;
+
+ X509Certificate2 data = await certificate.Find();
+
+ if (data != null)
+ {
+ // fill in subject name.
+ StringBuilder buffer = new StringBuilder();
+
+ foreach (string element in X509Utils.ParseDistinguishedName(data.Subject))
+ {
+ if (element.StartsWith("CN="))
+ {
+ ApplicationNameTB.Text = element.Substring(3);
+ }
+
+ if (element.StartsWith("O="))
+ {
+
+ OrganizationTB.Text = element.Substring(2);
+ }
+
+ if (buffer.Length > 0)
+ {
+ buffer.Append('/');
+ }
+
+ buffer.Append(element);
+ }
+
+ if (buffer.Length > 0)
+ {
+ SubjectNameTB.Text = buffer.ToString();
+ }
+
+ // fill in issuer name.
+ buffer = new StringBuilder();
+
+ foreach (string element in X509Utils.ParseDistinguishedName(data.Issuer))
+ {
+ if (buffer.Length > 0)
+ {
+ buffer.Append('/');
+ }
+
+ buffer.Append(element);
+ }
+
+ if (buffer.Length > 0)
+ {
+ IssuerNameTB.Text = buffer.ToString();
+ }
+
+ // fill in application uri.
+ string applicationUri = X509Utils.GetApplicationUriFromCertificate(data);
+
+ if (!String.IsNullOrEmpty(applicationUri))
+ {
+ ApplicationUriTB.Text = applicationUri;
+ }
+
+ // fill in domains.
+ buffer = new StringBuilder();
+
+ foreach (string domain in X509Utils.GetDomainsFromCertficate(data))
+ {
+ if (buffer.Length > 0)
+ {
+ buffer.Append(", ");
+ }
+
+ buffer.Append(domain);
+ }
+
+ if (buffer.Length > 0)
+ {
+ DomainsTB.Text = buffer.ToString();
+ }
+
+ ValidFromTB.Text = data.NotBefore.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
+ ValidToTB.Text = data.NotAfter.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
+ ThumbprintTB.Text = data.Thumbprint;
+ }
+ }
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private async void DetailsBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ await new CertificateDlg().ShowDialog(m_certificate);
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private async void ExportBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ const string caption = "Export Certificate";
+
+ if (m_currentDirectory == null)
+ {
+ m_currentDirectory = Utils.GetAbsoluteDirectoryPath("%LocalApplicationData%", false, false, false);
+ }
+
+ if (m_currentDirectory == null)
+ {
+ m_currentDirectory = Environment.CurrentDirectory;
+ }
+
+ X509Certificate2 certificate = await m_certificate.Find();
+
+ if (certificate == null)
+ {
+ MessageBox.Show("Cannot export an invalid certificate.", caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+
+ string displayName = null;
+
+ foreach (string element in X509Utils.ParseDistinguishedName(certificate.Subject))
+ {
+ if (element.StartsWith("CN="))
+ {
+ displayName = element.Substring(3);
+ break;
+ }
+ }
+
+ StringBuilder filePath = new StringBuilder();
+
+ if (!String.IsNullOrEmpty(displayName))
+ {
+ filePath.Append(displayName);
+ filePath.Append(" ");
+ }
+
+ filePath.Append("[");
+ filePath.Append(certificate.Thumbprint);
+ filePath.Append("].der");
+
+ SaveFileDialog dialog = new SaveFileDialog();
+
+ dialog.CheckFileExists = false;
+ dialog.CheckPathExists = true;
+ dialog.DefaultExt = ".der";
+ dialog.Filter = "Certificate Files (*.der)|*.der|All Files (*.*)|*.*";
+ dialog.ValidateNames = true;
+ dialog.Title = "Save Certificate File";
+ dialog.FileName = filePath.ToString();
+ dialog.InitialDirectory = m_currentDirectory;
+
+ if (dialog.ShowDialog() != DialogResult.OK)
+ {
+ return;
+ }
+
+ FileInfo fileInfo = new FileInfo(dialog.FileName);
+ m_currentDirectory = fileInfo.DirectoryName;
+
+ // save the file.
+ using (Stream ostrm = fileInfo.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None))
+ {
+ byte[] data = certificate.RawData;
+ ostrm.Write(data, 0, data.Length);
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, System.Reflection.MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/ViewCertificateDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.Designer.cs
new file mode 100644
index 00000000..fd246d78
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.Designer.cs
@@ -0,0 +1,166 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class YesNoDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.YesToAllBTN = new System.Windows.Forms.Button();
+ this.YesBTN = new System.Windows.Forms.Button();
+ this.NoBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.MessageLB = new System.Windows.Forms.Label();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.YesToAllBTN);
+ this.ButtonsPN.Controls.Add(this.YesBTN);
+ this.ButtonsPN.Controls.Add(this.NoBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 21);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(242, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // YesToAllBTN
+ //
+ this.YesToAllBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
+ this.YesToAllBTN.DialogResult = System.Windows.Forms.DialogResult.Retry;
+ this.YesToAllBTN.Location = new System.Drawing.Point(84, 4);
+ this.YesToAllBTN.Name = "YesToAllBTN";
+ this.YesToAllBTN.Size = new System.Drawing.Size(75, 23);
+ this.YesToAllBTN.TabIndex = 2;
+ this.YesToAllBTN.Text = "Yes To All";
+ this.YesToAllBTN.UseVisualStyleBackColor = true;
+ //
+ // YesBTN
+ //
+ this.YesBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.YesBTN.DialogResult = System.Windows.Forms.DialogResult.Yes;
+ this.YesBTN.Location = new System.Drawing.Point(4, 4);
+ this.YesBTN.Name = "YesBTN";
+ this.YesBTN.Size = new System.Drawing.Size(75, 23);
+ this.YesBTN.TabIndex = 0;
+ this.YesBTN.Text = "Yes";
+ this.YesBTN.UseVisualStyleBackColor = true;
+ //
+ // NoBTN
+ //
+ this.NoBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.NoBTN.DialogResult = System.Windows.Forms.DialogResult.No;
+ this.NoBTN.Location = new System.Drawing.Point(163, 4);
+ this.NoBTN.Name = "NoBTN";
+ this.NoBTN.Size = new System.Drawing.Size(75, 23);
+ this.NoBTN.TabIndex = 1;
+ this.NoBTN.Text = "No";
+ this.NoBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.AutoSize = true;
+ this.MainPN.Controls.Add(this.MessageLB);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(3, 3, 3, 0);
+ this.MainPN.Size = new System.Drawing.Size(242, 21);
+ this.MainPN.TabIndex = 1;
+ //
+ // MessageLB
+ //
+ this.MessageLB.AutoSize = true;
+ this.MessageLB.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MessageLB.Location = new System.Drawing.Point(3, 3);
+ this.MessageLB.Name = "MessageLB";
+ this.MessageLB.Size = new System.Drawing.Size(35, 13);
+ this.MessageLB.TabIndex = 0;
+ this.MessageLB.Text = "label1";
+ //
+ // YesNoDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoSize = true;
+ this.CancelButton = this.NoBTN;
+ this.ClientSize = new System.Drawing.Size(242, 52);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "YesNoDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Caption";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.MainPN.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button YesBTN;
+ private System.Windows.Forms.Button NoBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.Label MessageLB;
+ private System.Windows.Forms.Button YesToAllBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.cs
new file mode 100644
index 00000000..5a25c7cf
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.cs
@@ -0,0 +1,74 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Prompts the user to answer a yes-no question.
+ ///
+ public partial class YesNoDlg : Form
+ {
+ ///
+ /// Contructs the object.
+ ///
+ public YesNoDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+
+ ///
+ /// Displays the dialog.
+ ///
+ public DialogResult ShowDialog(string message, string caption)
+ {
+ return ShowDialog(message, caption, false);
+ }
+
+ ///
+ /// Displays the dialog.
+ ///
+ public DialogResult ShowDialog(string message, string caption, bool yesToAll)
+ {
+ this.YesToAllBTN.Visible = yesToAll;
+ this.Text = caption;
+ this.MessageLB.Text = message;
+ return ShowDialog();
+ }
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Configuration/YesNoDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.Designer.cs
new file mode 100644
index 00000000..27f1d993
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.Designer.cs
@@ -0,0 +1,510 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ConfiguredServerDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.RefreshBTN = new System.Windows.Forms.Button();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.UserSecurityPoliciesLB = new System.Windows.Forms.Label();
+ this.UserSecurityPoliciesTB = new System.Windows.Forms.TextBox();
+ this.DiscoveryProfileURI = new System.Windows.Forms.Label();
+ this.GatewayServerURI = new System.Windows.Forms.Label();
+ this.DiscoveryProfileUriTB = new System.Windows.Forms.TextBox();
+ this.GatewayServerUriTB = new System.Windows.Forms.TextBox();
+ this.EndpointListLB = new System.Windows.Forms.ListBox();
+ this.TransportProfileUriLB = new System.Windows.Forms.Label();
+ this.ProductUriLB = new System.Windows.Forms.Label();
+ this.ApplicationUriLB = new System.Windows.Forms.Label();
+ this.ApplicationTypeLB = new System.Windows.Forms.Label();
+ this.ApplicationNameLB = new System.Windows.Forms.Label();
+ this.TransportProfileUriTB = new System.Windows.Forms.TextBox();
+ this.ProductUriTB = new System.Windows.Forms.TextBox();
+ this.ApplicationUriTB = new System.Windows.Forms.TextBox();
+ this.ApplicationTypeTB = new System.Windows.Forms.TextBox();
+ this.ApplicationNameTB = new System.Windows.Forms.TextBox();
+ this.StatusTB = new System.Windows.Forms.TextBox();
+ this.EncodingCB = new System.Windows.Forms.ComboBox();
+ this.SecurityModeCB = new System.Windows.Forms.ComboBox();
+ this.SecurityPolicyCB = new System.Windows.Forms.ComboBox();
+ this.ProtocolCB = new System.Windows.Forms.ComboBox();
+ this.EncodingLB = new System.Windows.Forms.Label();
+ this.SecurityModeLB = new System.Windows.Forms.Label();
+ this.SecurityPolicyLB = new System.Windows.Forms.Label();
+ this.ProtocolLB = new System.Windows.Forms.Label();
+ this.SecurityLevelLB = new System.Windows.Forms.Label();
+ this.SecurityLevelTB = new System.Windows.Forms.TextBox();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.RefreshBTN);
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 370);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(799, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // RefreshBTN
+ //
+ this.RefreshBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
+ this.RefreshBTN.Location = new System.Drawing.Point(362, 4);
+ this.RefreshBTN.Name = "RefreshBTN";
+ this.RefreshBTN.Size = new System.Drawing.Size(75, 23);
+ this.RefreshBTN.TabIndex = 2;
+ this.RefreshBTN.Text = "Refresh";
+ this.RefreshBTN.UseVisualStyleBackColor = true;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(720, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.SecurityLevelTB);
+ this.MainPN.Controls.Add(this.SecurityLevelLB);
+ this.MainPN.Controls.Add(this.UserSecurityPoliciesLB);
+ this.MainPN.Controls.Add(this.UserSecurityPoliciesTB);
+ this.MainPN.Controls.Add(this.DiscoveryProfileURI);
+ this.MainPN.Controls.Add(this.GatewayServerURI);
+ this.MainPN.Controls.Add(this.DiscoveryProfileUriTB);
+ this.MainPN.Controls.Add(this.GatewayServerUriTB);
+ this.MainPN.Controls.Add(this.EndpointListLB);
+ this.MainPN.Controls.Add(this.TransportProfileUriLB);
+ this.MainPN.Controls.Add(this.ProductUriLB);
+ this.MainPN.Controls.Add(this.ApplicationUriLB);
+ this.MainPN.Controls.Add(this.ApplicationTypeLB);
+ this.MainPN.Controls.Add(this.ApplicationNameLB);
+ this.MainPN.Controls.Add(this.TransportProfileUriTB);
+ this.MainPN.Controls.Add(this.ProductUriTB);
+ this.MainPN.Controls.Add(this.ApplicationUriTB);
+ this.MainPN.Controls.Add(this.ApplicationTypeTB);
+ this.MainPN.Controls.Add(this.ApplicationNameTB);
+ this.MainPN.Controls.Add(this.StatusTB);
+ this.MainPN.Controls.Add(this.EncodingCB);
+ this.MainPN.Controls.Add(this.SecurityModeCB);
+ this.MainPN.Controls.Add(this.SecurityPolicyCB);
+ this.MainPN.Controls.Add(this.ProtocolCB);
+ this.MainPN.Controls.Add(this.EncodingLB);
+ this.MainPN.Controls.Add(this.SecurityModeLB);
+ this.MainPN.Controls.Add(this.SecurityPolicyLB);
+ this.MainPN.Controls.Add(this.ProtocolLB);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Size = new System.Drawing.Size(799, 401);
+ this.MainPN.TabIndex = 0;
+ //
+ // UserSecurityPoliciesLB
+ //
+ this.UserSecurityPoliciesLB.AutoSize = true;
+ this.UserSecurityPoliciesLB.Location = new System.Drawing.Point(368, 299);
+ this.UserSecurityPoliciesLB.Name = "UserSecurityPoliciesLB";
+ this.UserSecurityPoliciesLB.Size = new System.Drawing.Size(109, 13);
+ this.UserSecurityPoliciesLB.TabIndex = 38;
+ this.UserSecurityPoliciesLB.Text = "User Security Policies";
+ this.UserSecurityPoliciesLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // UserSecurityPoliciesTB
+ //
+ this.UserSecurityPoliciesTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.UserSecurityPoliciesTB.Location = new System.Drawing.Point(487, 296);
+ this.UserSecurityPoliciesTB.Name = "UserSecurityPoliciesTB";
+ this.UserSecurityPoliciesTB.ReadOnly = true;
+ this.UserSecurityPoliciesTB.Size = new System.Drawing.Size(300, 20);
+ this.UserSecurityPoliciesTB.TabIndex = 37;
+ //
+ // DiscoveryProfileURI
+ //
+ this.DiscoveryProfileURI.AutoSize = true;
+ this.DiscoveryProfileURI.Location = new System.Drawing.Point(368, 273);
+ this.DiscoveryProfileURI.Name = "DiscoveryProfileURI";
+ this.DiscoveryProfileURI.Size = new System.Drawing.Size(108, 13);
+ this.DiscoveryProfileURI.TabIndex = 36;
+ this.DiscoveryProfileURI.Text = "Discovery Profile URI";
+ this.DiscoveryProfileURI.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // GatewayServerURI
+ //
+ this.GatewayServerURI.AutoSize = true;
+ this.GatewayServerURI.Location = new System.Drawing.Point(368, 247);
+ this.GatewayServerURI.Name = "GatewayServerURI";
+ this.GatewayServerURI.Size = new System.Drawing.Size(105, 13);
+ this.GatewayServerURI.TabIndex = 35;
+ this.GatewayServerURI.Text = "Gateway Server URI";
+ this.GatewayServerURI.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // DiscoveryProfileUriTB
+ //
+ this.DiscoveryProfileUriTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.DiscoveryProfileUriTB.Location = new System.Drawing.Point(487, 270);
+ this.DiscoveryProfileUriTB.Name = "DiscoveryProfileUriTB";
+ this.DiscoveryProfileUriTB.ReadOnly = true;
+ this.DiscoveryProfileUriTB.Size = new System.Drawing.Size(300, 20);
+ this.DiscoveryProfileUriTB.TabIndex = 34;
+ //
+ // GatewayServerUriTB
+ //
+ this.GatewayServerUriTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.GatewayServerUriTB.Location = new System.Drawing.Point(487, 244);
+ this.GatewayServerUriTB.Name = "GatewayServerUriTB";
+ this.GatewayServerUriTB.ReadOnly = true;
+ this.GatewayServerUriTB.Size = new System.Drawing.Size(300, 20);
+ this.GatewayServerUriTB.TabIndex = 33;
+ //
+ // EndpointListLB
+ //
+ this.EndpointListLB.FormattingEnabled = true;
+ this.EndpointListLB.HorizontalScrollbar = true;
+ this.EndpointListLB.Location = new System.Drawing.Point(12, 12);
+ this.EndpointListLB.Name = "EndpointListLB";
+ this.EndpointListLB.Size = new System.Drawing.Size(350, 329);
+ this.EndpointListLB.TabIndex = 32;
+ this.EndpointListLB.SelectedIndexChanged += new System.EventHandler(this.EndpointListLB_SelectedIndexChanged);
+ //
+ // TransportProfileUriLB
+ //
+ this.TransportProfileUriLB.AutoSize = true;
+ this.TransportProfileUriLB.Location = new System.Drawing.Point(368, 221);
+ this.TransportProfileUriLB.Name = "TransportProfileUriLB";
+ this.TransportProfileUriLB.Size = new System.Drawing.Size(106, 13);
+ this.TransportProfileUriLB.TabIndex = 31;
+ this.TransportProfileUriLB.Text = "Transport Profile URI";
+ this.TransportProfileUriLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ProductUriLB
+ //
+ this.ProductUriLB.AutoSize = true;
+ this.ProductUriLB.Location = new System.Drawing.Point(368, 195);
+ this.ProductUriLB.Name = "ProductUriLB";
+ this.ProductUriLB.Size = new System.Drawing.Size(66, 13);
+ this.ProductUriLB.TabIndex = 30;
+ this.ProductUriLB.Text = "Product URI";
+ this.ProductUriLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ApplicationUriLB
+ //
+ this.ApplicationUriLB.AutoSize = true;
+ this.ApplicationUriLB.Location = new System.Drawing.Point(368, 169);
+ this.ApplicationUriLB.Name = "ApplicationUriLB";
+ this.ApplicationUriLB.Size = new System.Drawing.Size(81, 13);
+ this.ApplicationUriLB.TabIndex = 29;
+ this.ApplicationUriLB.Text = "Application URI";
+ this.ApplicationUriLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ApplicationTypeLB
+ //
+ this.ApplicationTypeLB.AutoSize = true;
+ this.ApplicationTypeLB.Location = new System.Drawing.Point(368, 143);
+ this.ApplicationTypeLB.Name = "ApplicationTypeLB";
+ this.ApplicationTypeLB.Size = new System.Drawing.Size(86, 13);
+ this.ApplicationTypeLB.TabIndex = 28;
+ this.ApplicationTypeLB.Text = "Application Type";
+ this.ApplicationTypeLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ApplicationNameLB
+ //
+ this.ApplicationNameLB.AutoSize = true;
+ this.ApplicationNameLB.Location = new System.Drawing.Point(368, 117);
+ this.ApplicationNameLB.Name = "ApplicationNameLB";
+ this.ApplicationNameLB.Size = new System.Drawing.Size(90, 13);
+ this.ApplicationNameLB.TabIndex = 27;
+ this.ApplicationNameLB.Text = "Application Name";
+ this.ApplicationNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // TransportProfileUriTB
+ //
+ this.TransportProfileUriTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.TransportProfileUriTB.Location = new System.Drawing.Point(487, 218);
+ this.TransportProfileUriTB.Name = "TransportProfileUriTB";
+ this.TransportProfileUriTB.ReadOnly = true;
+ this.TransportProfileUriTB.Size = new System.Drawing.Size(300, 20);
+ this.TransportProfileUriTB.TabIndex = 26;
+ //
+ // ProductUriTB
+ //
+ this.ProductUriTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ProductUriTB.Location = new System.Drawing.Point(487, 192);
+ this.ProductUriTB.Name = "ProductUriTB";
+ this.ProductUriTB.ReadOnly = true;
+ this.ProductUriTB.Size = new System.Drawing.Size(300, 20);
+ this.ProductUriTB.TabIndex = 25;
+ //
+ // ApplicationUriTB
+ //
+ this.ApplicationUriTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ApplicationUriTB.Location = new System.Drawing.Point(487, 166);
+ this.ApplicationUriTB.Name = "ApplicationUriTB";
+ this.ApplicationUriTB.ReadOnly = true;
+ this.ApplicationUriTB.Size = new System.Drawing.Size(300, 20);
+ this.ApplicationUriTB.TabIndex = 24;
+ //
+ // ApplicationTypeTB
+ //
+ this.ApplicationTypeTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ApplicationTypeTB.Location = new System.Drawing.Point(487, 140);
+ this.ApplicationTypeTB.Name = "ApplicationTypeTB";
+ this.ApplicationTypeTB.ReadOnly = true;
+ this.ApplicationTypeTB.Size = new System.Drawing.Size(300, 20);
+ this.ApplicationTypeTB.TabIndex = 23;
+ //
+ // ApplicationNameTB
+ //
+ this.ApplicationNameTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ApplicationNameTB.Location = new System.Drawing.Point(487, 114);
+ this.ApplicationNameTB.Name = "ApplicationNameTB";
+ this.ApplicationNameTB.ReadOnly = true;
+ this.ApplicationNameTB.Size = new System.Drawing.Size(300, 20);
+ this.ApplicationNameTB.TabIndex = 22;
+ //
+ // StatusTB
+ //
+ this.StatusTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.StatusTB.Location = new System.Drawing.Point(12, 347);
+ this.StatusTB.Name = "StatusTB";
+ this.StatusTB.ReadOnly = true;
+ this.StatusTB.Size = new System.Drawing.Size(775, 20);
+ this.StatusTB.TabIndex = 21;
+ //
+ // EncodingCB
+ //
+ this.EncodingCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.EncodingCB.FormattingEnabled = true;
+ this.EncodingCB.Location = new System.Drawing.Point(487, 87);
+ this.EncodingCB.Name = "EncodingCB";
+ this.EncodingCB.Size = new System.Drawing.Size(181, 21);
+ this.EncodingCB.TabIndex = 7;
+ //
+ // SecurityModeCB
+ //
+ this.SecurityModeCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.SecurityModeCB.FormattingEnabled = true;
+ this.SecurityModeCB.Location = new System.Drawing.Point(487, 33);
+ this.SecurityModeCB.Name = "SecurityModeCB";
+ this.SecurityModeCB.Size = new System.Drawing.Size(181, 21);
+ this.SecurityModeCB.TabIndex = 3;
+ this.SecurityModeCB.SelectedIndexChanged += new System.EventHandler(this.SecurityModeCB_SelectedIndexChanged);
+ //
+ // SecurityPolicyCB
+ //
+ this.SecurityPolicyCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.SecurityPolicyCB.FormattingEnabled = true;
+ this.SecurityPolicyCB.Location = new System.Drawing.Point(487, 60);
+ this.SecurityPolicyCB.Name = "SecurityPolicyCB";
+ this.SecurityPolicyCB.Size = new System.Drawing.Size(181, 21);
+ this.SecurityPolicyCB.TabIndex = 5;
+ this.SecurityPolicyCB.SelectedIndexChanged += new System.EventHandler(this.SecurityPolicyCB_SelectedIndexChanged);
+ //
+ // ProtocolCB
+ //
+ this.ProtocolCB.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.ProtocolCB.FormattingEnabled = true;
+ this.ProtocolCB.Location = new System.Drawing.Point(487, 6);
+ this.ProtocolCB.Name = "ProtocolCB";
+ this.ProtocolCB.Size = new System.Drawing.Size(181, 21);
+ this.ProtocolCB.TabIndex = 1;
+ this.ProtocolCB.SelectedIndexChanged += new System.EventHandler(this.ProtocolCB_SelectedIndexChanged);
+ //
+ // EncodingLB
+ //
+ this.EncodingLB.AutoSize = true;
+ this.EncodingLB.Location = new System.Drawing.Point(368, 90);
+ this.EncodingLB.Name = "EncodingLB";
+ this.EncodingLB.Size = new System.Drawing.Size(98, 13);
+ this.EncodingLB.TabIndex = 6;
+ this.EncodingLB.Text = "Message Encoding";
+ this.EncodingLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // SecurityModeLB
+ //
+ this.SecurityModeLB.AutoSize = true;
+ this.SecurityModeLB.Location = new System.Drawing.Point(368, 36);
+ this.SecurityModeLB.Name = "SecurityModeLB";
+ this.SecurityModeLB.Size = new System.Drawing.Size(75, 13);
+ this.SecurityModeLB.TabIndex = 2;
+ this.SecurityModeLB.Text = "Security Mode";
+ this.SecurityModeLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // SecurityPolicyLB
+ //
+ this.SecurityPolicyLB.AutoSize = true;
+ this.SecurityPolicyLB.Location = new System.Drawing.Point(368, 63);
+ this.SecurityPolicyLB.Name = "SecurityPolicyLB";
+ this.SecurityPolicyLB.Size = new System.Drawing.Size(76, 13);
+ this.SecurityPolicyLB.TabIndex = 4;
+ this.SecurityPolicyLB.Text = "Security Policy";
+ this.SecurityPolicyLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // ProtocolLB
+ //
+ this.ProtocolLB.AutoSize = true;
+ this.ProtocolLB.Location = new System.Drawing.Point(368, 9);
+ this.ProtocolLB.Name = "ProtocolLB";
+ this.ProtocolLB.Size = new System.Drawing.Size(46, 13);
+ this.ProtocolLB.TabIndex = 0;
+ this.ProtocolLB.Text = "Protocol";
+ this.ProtocolLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // SecurityLevelLB
+ //
+ this.SecurityLevelLB.AutoSize = true;
+ this.SecurityLevelLB.Location = new System.Drawing.Point(368, 325);
+ this.SecurityLevelLB.Name = "SecurityLevelLB";
+ this.SecurityLevelLB.Size = new System.Drawing.Size(71, 13);
+ this.SecurityLevelLB.TabIndex = 39;
+ this.SecurityLevelLB.Text = "SecurityLevel";
+ this.SecurityLevelLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // SecurityLevelTB
+ //
+ this.SecurityLevelTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.SecurityLevelTB.Location = new System.Drawing.Point(487, 322);
+ this.SecurityLevelTB.Name = "SecurityLevelTB";
+ this.SecurityLevelTB.ReadOnly = true;
+ this.SecurityLevelTB.Size = new System.Drawing.Size(300, 20);
+ this.SecurityLevelTB.TabIndex = 40;
+ //
+ // ConfiguredServerDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(799, 401);
+ this.Controls.Add(this.ButtonsPN);
+ this.Controls.Add(this.MainPN);
+ this.MaximumSize = new System.Drawing.Size(1920, 439);
+ this.MinimumSize = new System.Drawing.Size(16, 439);
+ this.Name = "ConfiguredServerDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Server Configuration";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.MainPN.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.Label ProtocolLB;
+ private System.Windows.Forms.Label SecurityPolicyLB;
+ private System.Windows.Forms.Label EncodingLB;
+ private System.Windows.Forms.Label SecurityModeLB;
+ private System.Windows.Forms.ComboBox ProtocolCB;
+ private System.Windows.Forms.ComboBox SecurityPolicyCB;
+ private System.Windows.Forms.ComboBox SecurityModeCB;
+ private System.Windows.Forms.ComboBox EncodingCB;
+ private System.Windows.Forms.Button RefreshBTN;
+ private System.Windows.Forms.TextBox StatusTB;
+ private System.Windows.Forms.Label ApplicationNameLB;
+ private System.Windows.Forms.TextBox TransportProfileUriTB;
+ private System.Windows.Forms.TextBox ProductUriTB;
+ private System.Windows.Forms.TextBox ApplicationUriTB;
+ private System.Windows.Forms.TextBox ApplicationTypeTB;
+ private System.Windows.Forms.TextBox ApplicationNameTB;
+ private System.Windows.Forms.Label TransportProfileUriLB;
+ private System.Windows.Forms.Label ProductUriLB;
+ private System.Windows.Forms.Label ApplicationUriLB;
+ private System.Windows.Forms.Label ApplicationTypeLB;
+ private System.Windows.Forms.ListBox EndpointListLB;
+ private System.Windows.Forms.Label DiscoveryProfileURI;
+ private System.Windows.Forms.Label GatewayServerURI;
+ private System.Windows.Forms.TextBox DiscoveryProfileUriTB;
+ private System.Windows.Forms.TextBox GatewayServerUriTB;
+ private System.Windows.Forms.Label UserSecurityPoliciesLB;
+ private System.Windows.Forms.TextBox UserSecurityPoliciesTB;
+ private System.Windows.Forms.TextBox SecurityLevelTB;
+ private System.Windows.Forms.Label SecurityLevelLB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.cs
new file mode 100644
index 00000000..cb7b99fd
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.cs
@@ -0,0 +1,1832 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using System.Threading;
+using System.Security.Cryptography.X509Certificates;
+using Opc.Ua.Security.Certificates;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Prompts the user to edit a ComPseudoServerDlg.
+ ///
+ public partial class ConfiguredServerDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes the dialog.
+ ///
+ public ConfiguredServerDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+
+ m_userIdentities = new Dictionary();
+ m_statusObject = new StatusObject((int)StatusChannel.MaxStatusChannels);
+ }
+ #endregion
+
+ #region Private Fields
+ ///
+ /// The possible encodings.
+ ///
+ private enum Encoding
+ {
+ Default,
+ Xml,
+ Binary
+ }
+
+ ///
+ /// The type of status (for coloring the status textbox).
+ ///
+ private enum StatusType
+ {
+ Ok = 0,
+ Warning = 1,
+ Error = 2
+ }
+
+ ///
+ /// The status channel inside the StatusObject.
+ ///
+ private enum StatusChannel
+ {
+ Discovery = 0,
+ SelectedSecurityMode = 1,
+ ApplicationType = 2,
+ SelectedProtocol = 3,
+ ApplicationUri = 4,
+ DiscoveryURLs = 5,
+ Server = 6,
+ DifferentCertificate = 7,
+ SecurityPolicyUri = 8,
+ TransportProfileUri = 9,
+ SelectedSecurityPolicy = 10,
+ MaxStatusChannels = 11
+ }
+
+ ///
+ /// Whether to override limits
+ ///
+ private enum UseDefaultLimits
+ {
+ Yes,
+ No
+ }
+
+ ///
+ /// This class merges multiple error/warning/status codes from multiple sources.
+ /// Initialize it with the number of status channels and update "StatusChannel" accordingly.
+ /// Provides a general view of all the statuses (joined texts, worst status).
+ ///
+ private class StatusObject
+ {
+ public StatusObject(int maxChannels)
+ {
+ m_maxChannels = maxChannels;
+ m_statusTexts = new string[maxChannels];
+ m_statusTypes = new StatusType[maxChannels];
+
+ for (int i = 0; i < m_maxChannels; ++i)
+ {
+ m_statusTexts[i] = String.Empty;
+ m_statusTypes[i] = StatusType.Ok;
+ }
+ }
+
+ public String StatusString
+ {
+ get
+ {
+ String status = String.Empty;
+
+ for (int i = 0; i < m_maxChannels; ++i)
+ {
+ if (!String.IsNullOrEmpty(m_statusTexts[i]))
+ {
+ if (!String.IsNullOrEmpty(status))
+ {
+ status += " | ";
+ }
+
+ status += m_statusTexts[i];
+ }
+ }
+
+ return status;
+ }
+ }
+
+ public StatusType StatusType
+ {
+ get
+ {
+ StatusType type = StatusType.Ok;
+
+ for (int i = 0; i < m_maxChannels; ++i)
+ {
+ if (m_statusTypes[i] > type)
+ {
+ type = m_statusTypes[i];
+ }
+ }
+
+ return type;
+ }
+ }
+
+ public void SetStatus(StatusChannel channel, String text, StatusType type)
+ {
+ int intChannel = (int)channel;
+
+ if ((intChannel >= 0) && (intChannel < m_maxChannels))
+ {
+ m_statusTexts[intChannel] = text;
+ m_statusTypes[intChannel] = type;
+ }
+ }
+
+ public void ClearStatus(StatusChannel channel)
+ {
+ int intChannel = (int)channel;
+
+ if ((intChannel >= 0) && (intChannel < m_maxChannels))
+ {
+ m_statusTexts[intChannel] = String.Empty;
+ m_statusTypes[intChannel] = StatusType.Ok;
+ }
+ }
+
+ private int m_maxChannels;
+ private String[] m_statusTexts;
+ private StatusType[] m_statusTypes;
+ }
+
+ ///
+ /// This class is used by the EndopintListLB (list box).
+ /// Holds references to the received EndpointDescription and its MessageSecurityMode, SecurityPolicyUri, MessageSecurityMode and EncodingSupport.
+ /// Also prepares a user-friendly text representation of all the endpoint-rellevant characteristics.
+ /// The extracted EndpointDescription properties are used in selecting the right combo-box values when user clicks in the endpoint list box.
+ ///
+ private class EndpointDescriptionString
+ {
+ public EndpointDescriptionString(EndpointDescription endpointDescription)
+ {
+ m_endpointDescription = endpointDescription;
+ m_protocol = new Protocol(endpointDescription);
+ m_currentPolicy = SecurityPolicies.GetDisplayName(endpointDescription.SecurityPolicyUri);
+ m_messageSecurityMode = endpointDescription.SecurityMode;
+
+ switch (m_endpointDescription.EncodingSupport)
+ {
+ case BinaryEncodingSupport.None:
+ {
+ m_encoding = Encoding.Xml;
+ break;
+ }
+
+ case BinaryEncodingSupport.Optional:
+ case BinaryEncodingSupport.Required:
+ {
+ m_encoding = Encoding.Binary;
+ break;
+ }
+ }
+
+ BuildEndpointDescription();
+ }
+
+ public EndpointDescription EndpointDescription
+ {
+ get
+ {
+ return m_endpointDescription;
+ }
+ }
+
+ public Protocol Protocol
+ {
+ get
+ {
+ return m_protocol;
+ }
+ }
+
+ public string CurrentPolicy
+ {
+ get
+ {
+ return m_currentPolicy;
+ }
+ }
+
+ public MessageSecurityMode MessageSecurityMode
+ {
+ get
+ {
+ return m_messageSecurityMode;
+ }
+ }
+
+ public Encoding Encoding
+ {
+ get
+ {
+ return m_encoding;
+ }
+ }
+
+ public override string ToString()
+ {
+ return m_stringRepresentation;
+ }
+
+ private void BuildEndpointDescription()
+ {
+ m_stringRepresentation = m_protocol.ToString() + " - ";
+ m_stringRepresentation += m_endpointDescription.SecurityMode + " - ";
+ m_stringRepresentation += SecurityPolicies.GetDisplayName(m_endpointDescription.SecurityPolicyUri) + " - ";
+
+ switch (m_endpointDescription.EncodingSupport)
+ {
+ case BinaryEncodingSupport.None:
+ {
+ m_stringRepresentation += Encoding.Xml;
+ break;
+ }
+
+ case BinaryEncodingSupport.Required:
+ {
+ m_stringRepresentation += Encoding.Binary;
+ break;
+ }
+
+ case BinaryEncodingSupport.Optional:
+ {
+ m_stringRepresentation += Encoding.Binary + "/" + Encoding.Xml;
+ break;
+ }
+ }
+
+ }
+
+ private Protocol m_protocol;
+ private EndpointDescription m_endpointDescription;
+ private MessageSecurityMode m_messageSecurityMode;
+ private string m_currentPolicy;
+ private Encoding m_encoding;
+ private string m_stringRepresentation;
+ }
+
+ private ConfiguredEndpoint m_endpoint;
+ private EndpointDescription m_currentDescription;
+ private EndpointDescriptionCollection m_availableEndpoints;
+ private List m_availableEndpointsDescriptions;
+ private int m_discoveryTimeout;
+ private int m_discoverCount;
+ private ApplicationConfiguration m_configuration;
+ private bool m_updating;
+ private bool m_selecting;
+ private Dictionary m_userIdentities;
+ private EndpointConfiguration m_endpointConfiguration;
+ private bool m_discoverySucceeded;
+ private Uri m_discoveryUrl;
+ private bool m_showAllOptions;
+ private StatusObject m_statusObject;
+ #endregion
+
+ #region Public Interface
+ public EndpointDescriptionCollection AvailableEnpoints
+ {
+ get { return m_availableEndpoints; }
+ }
+
+ ///
+ /// The timeout in milliseconds to use when discovering servers.
+ ///
+ [System.ComponentModel.DefaultValue(20000)]
+ public int DiscoveryTimeout
+ {
+ get { return m_discoveryTimeout; }
+ set { Interlocked.Exchange(ref m_discoveryTimeout, value); }
+ }
+ ///
+ /// Displays the dialog.
+ ///
+ public ConfiguredEndpoint ShowDialog(ApplicationDescription server, ApplicationConfiguration configuration)
+ {
+ if (server == null) throw new ArgumentNullException("server");
+
+ m_configuration = configuration;
+
+ // construct a list of available endpoint descriptions for the application.
+ m_availableEndpoints = new EndpointDescriptionCollection();
+ m_availableEndpointsDescriptions = new List();
+ m_endpointConfiguration = EndpointConfiguration.Create(configuration);
+
+ // create a default endpoint description.
+ m_endpoint = null;
+ m_currentDescription = null;
+
+ // initializing the protocol will trigger an update to all other controls.
+ InitializeProtocols(m_availableEndpoints);
+ BuildEndpointDescriptionStrings(m_availableEndpoints);
+
+ // discover endpoints in the background.
+ m_discoverySucceeded = false;
+ Interlocked.Increment(ref m_discoverCount);
+ ThreadPool.QueueUserWorkItem(new WaitCallback(OnDiscoverEndpoints), server);
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_endpoint;
+ }
+
+ ///
+ /// Displays the dialog.
+ ///
+ public ConfiguredEndpoint ShowDialog(ConfiguredEndpoint endpoint, ApplicationConfiguration configuration)
+ {
+ if (endpoint == null) throw new ArgumentNullException("endpoint");
+
+ m_endpoint = endpoint;
+ m_configuration = configuration;
+
+ // construct a list of available endpoint descriptions for the application.
+ m_availableEndpoints = new EndpointDescriptionCollection();
+ m_availableEndpointsDescriptions = new List();
+
+ m_availableEndpoints.Add(endpoint.Description);
+ m_currentDescription = endpoint.Description;
+ m_endpointConfiguration = endpoint.Configuration;
+
+ if (m_endpointConfiguration == null)
+ {
+ m_endpointConfiguration = EndpointConfiguration.Create(configuration);
+ }
+
+ if (endpoint.Collection != null)
+ {
+ foreach (ConfiguredEndpoint existingEndpoint in endpoint.Collection.Endpoints)
+ {
+ if (existingEndpoint.Description.Server.ApplicationUri == endpoint.Description.Server.ApplicationUri)
+ {
+ m_availableEndpoints.Add(existingEndpoint.Description);
+ }
+ }
+ }
+
+ BuildEndpointDescriptionStrings(m_availableEndpoints);
+
+ UserTokenPolicy policy = m_endpoint.SelectedUserTokenPolicy;
+
+ if (policy == null)
+ {
+ if (m_endpoint.Description.UserIdentityTokens.Count > 0)
+ {
+ policy = m_endpoint.Description.UserIdentityTokens[0];
+ }
+ }
+
+ if (policy != null)
+ {
+ UserTokenItem userTokenItem = new UserTokenItem(policy);
+
+ if (policy.TokenType == UserTokenType.UserName && m_endpoint.UserIdentity is UserNameIdentityToken)
+ {
+ m_userIdentities[userTokenItem.ToString()] = m_endpoint.UserIdentity;
+ }
+
+ if (policy.TokenType == UserTokenType.Certificate && m_endpoint.UserIdentity is X509IdentityToken)
+ {
+ m_userIdentities[userTokenItem.ToString()] = m_endpoint.UserIdentity;
+ }
+
+ if (policy.TokenType == UserTokenType.IssuedToken && m_endpoint.UserIdentity is IssuedIdentityToken)
+ {
+ m_userIdentities[userTokenItem.ToString()] = m_endpoint.UserIdentity;
+ }
+ }
+
+ // initializing the protocol will trigger an update to all other controls.
+ InitializeProtocols(m_availableEndpoints);
+
+ // check if the current settings match the defaults.
+ EndpointConfiguration defaultConfiguration = EndpointConfiguration.Create(configuration);
+
+ // discover endpoints in the background.
+ Interlocked.Increment(ref m_discoverCount);
+ ThreadPool.QueueUserWorkItem(new WaitCallback(OnDiscoverEndpoints), m_endpoint.Description.Server);
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_endpoint;
+ }
+ #endregion
+
+ #region Private Methods
+
+ ///
+ /// Creates the string representation of each EndpointDescription - to be used in the Endpoint Description List
+ ///
+ private void BuildEndpointDescriptionStrings(EndpointDescriptionCollection endpoints)
+ {
+ lock (m_availableEndpointsDescriptions)
+ {
+ m_availableEndpointsDescriptions.Clear();
+
+ foreach (EndpointDescription endpoint in endpoints)
+ {
+ m_availableEndpointsDescriptions.Add(new EndpointDescriptionString(endpoint));
+ }
+
+ InitializeEndpointList(m_availableEndpointsDescriptions);
+ }
+ }
+
+ ///
+ /// Returns true if the configuration is the same as the default.
+ ///
+ private bool SameAsDefaults(EndpointConfiguration defaultConfiguration, EndpointConfiguration currentConfiguration)
+ {
+ if (defaultConfiguration.ChannelLifetime != currentConfiguration.ChannelLifetime)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.MaxArrayLength != currentConfiguration.MaxArrayLength)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.MaxBufferSize != currentConfiguration.MaxBufferSize)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.MaxByteStringLength != currentConfiguration.MaxByteStringLength)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.MaxMessageSize != currentConfiguration.MaxMessageSize)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.MaxStringLength != currentConfiguration.MaxStringLength)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.OperationTimeout != currentConfiguration.OperationTimeout)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.SecurityTokenLifetime != currentConfiguration.SecurityTokenLifetime)
+ {
+ return false;
+ }
+
+ if (defaultConfiguration.UseBinaryEncoding != currentConfiguration.UseBinaryEncoding)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ ///
+ /// Finds the best match for the current protocol and security selections.
+ ///
+ private EndpointDescription FindBestEndpointDescription(EndpointDescriptionCollection endpoints)
+ {
+ // filter by the current protocol.
+ Protocol currentProtocol = (Protocol)ProtocolCB.SelectedItem;
+
+ // filter by the current security mode.
+ MessageSecurityMode currentMode = MessageSecurityMode.None;
+
+ if (SecurityModeCB.SelectedIndex != -1)
+ {
+ currentMode = (MessageSecurityMode)SecurityModeCB.SelectedItem;
+ }
+
+ // filter by the current security policy.
+ string currentPolicy = (string)SecurityPolicyCB.SelectedItem;
+
+ // find all matching descriptions.
+ EndpointDescriptionCollection matches = new EndpointDescriptionCollection();
+
+ if (endpoints != null)
+ {
+ foreach (EndpointDescription endpoint in endpoints)
+ {
+ Uri url = Utils.ParseUri(endpoint.EndpointUrl);
+
+ if (url == null)
+ {
+ continue;
+ }
+
+ if ((currentProtocol != null) && (!currentProtocol.Matches(url)))
+ {
+ continue;
+ }
+
+ if (currentMode != endpoint.SecurityMode)
+ {
+ continue;
+ }
+
+ if (currentPolicy != SecurityPolicies.GetDisplayName(endpoint.SecurityPolicyUri))
+ {
+ continue;
+ }
+
+ matches.Add(endpoint);
+ }
+ }
+
+ // check for no matches.
+ if (matches.Count == 0)
+ {
+ return null;
+ }
+
+ // check for single match.
+ if (matches.Count == 1)
+ {
+ return matches[0];
+ }
+
+ // choose highest priority.
+ EndpointDescription bestMatch = matches[0];
+
+ for (int ii = 1; ii < matches.Count; ii++)
+ {
+ if (bestMatch.SecurityLevel < matches[ii].SecurityLevel)
+ {
+ bestMatch = matches[ii];
+ }
+ }
+
+ return bestMatch;
+ }
+
+ private class Protocol
+ {
+ public Uri Url;
+ public string Profile;
+
+ public Protocol(string url)
+ {
+ Url = Utils.ParseUri(url);
+ }
+
+ public Protocol(EndpointDescription url)
+ {
+ Url = null;
+
+ if (url != null)
+ {
+ Url = Utils.ParseUri(url.EndpointUrl);
+
+ if ((Url != null) && (Url.Scheme == Utils.UriSchemeHttps))
+ {
+ switch (url.TransportProfileUri)
+ {
+ case Profiles.HttpsBinaryTransport:
+ {
+ Profile = "REST";
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public bool Matches(Uri url)
+ {
+ if (url == null || Url == null)
+ {
+ return false;
+ }
+
+ if (url.Scheme != Url.Scheme)
+ {
+ return false;
+ }
+
+ if (url.DnsSafeHost != Url.DnsSafeHost)
+ {
+ return false;
+ }
+
+ if (url.Port != Url.Port)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public override string ToString()
+ {
+ if (Url == null)
+ {
+ return String.Empty;
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.Append(Url.Scheme);
+
+ if (!String.IsNullOrEmpty(Profile))
+ {
+ builder.Append(" ");
+ builder.Append(Profile);
+ }
+
+ builder.Append(" [");
+ builder.Append(Url.DnsSafeHost);
+
+ if (Url.Port != -1)
+ {
+ builder.Append(":");
+ builder.Append(Url.Port);
+ }
+
+ builder.Append("]");
+
+ return builder.ToString();
+ }
+ }
+
+ ///
+ /// Initializes the protocol dropdown.
+ ///
+ private void InitializeProtocols(EndpointDescriptionCollection endpoints)
+ {
+ // preserve the existing value.
+ Protocol currentProtocol = (Protocol)ProtocolCB.SelectedItem;
+
+ ProtocolCB.Items.Clear();
+
+ // set all available protocols.
+ if (m_showAllOptions)
+ {
+ ProtocolCB.Items.Add(new Protocol("http://localhost"));
+ ProtocolCB.Items.Add(new Protocol("https://localhost"));
+ ProtocolCB.Items.Add(new Protocol("opc.tcp://localhost"));
+ }
+
+ // find all unique protocols.
+ else
+ {
+ if (endpoints != null)
+ {
+ foreach (EndpointDescription endpoint in endpoints)
+ {
+ Uri url = Utils.ParseUri(endpoint.EndpointUrl);
+
+ if (url != null)
+ {
+ bool found = false;
+
+ for (int ii = 0; ii < ProtocolCB.Items.Count; ii++)
+ {
+ if (((Protocol)ProtocolCB.Items[ii]).Matches(url))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ ProtocolCB.Items.Add(new Protocol(endpoint));
+ }
+ }
+ }
+ }
+
+ // add at least one protocol.
+ if (ProtocolCB.Items.Count == 0)
+ {
+ ProtocolCB.Items.Add(new Protocol("opc.tcp://localhost"));
+ }
+ }
+
+ // set the current value.
+ int index = 0;
+
+ if (currentProtocol != null)
+ {
+ index = 0;
+
+ for (int ii = 0; ii < ProtocolCB.Items.Count; ii++)
+ {
+ if (((Protocol)ProtocolCB.Items[ii]).Matches(currentProtocol.Url))
+ {
+ index = ii;
+ break;
+ }
+ }
+ }
+
+ ProtocolCB.SelectedIndex = index;
+ }
+
+ ///
+ /// Initializes the security modes dropdown.
+ ///
+ private void InitializeSecurityModes(EndpointDescriptionCollection endpoints)
+ {
+ // filter by the current protocol.
+ Protocol currentProtocol = (Protocol)ProtocolCB.SelectedItem;
+
+ // preserve the existing value.
+ MessageSecurityMode currentMode = MessageSecurityMode.None;
+
+ if (SecurityModeCB.SelectedIndex != -1)
+ {
+ currentMode = (MessageSecurityMode)SecurityModeCB.SelectedItem;
+ }
+
+ SecurityModeCB.Items.Clear();
+
+ // set all available security modes.
+ if (m_showAllOptions)
+ {
+ SecurityModeCB.Items.Add(MessageSecurityMode.None);
+ SecurityModeCB.Items.Add(MessageSecurityMode.Sign);
+ SecurityModeCB.Items.Add(MessageSecurityMode.SignAndEncrypt);
+ }
+
+ // find all unique security modes.
+ else
+ {
+ if (endpoints != null)
+ {
+ foreach (EndpointDescription endpoint in endpoints)
+ {
+ Uri url = Utils.ParseUri(endpoint.EndpointUrl);
+
+ if ((url != null) && (currentProtocol != null))
+ {
+ if (!currentProtocol.Matches(url))
+ {
+ continue;
+ }
+
+ if (!SecurityModeCB.Items.Contains(endpoint.SecurityMode))
+ {
+ SecurityModeCB.Items.Add(endpoint.SecurityMode);
+ }
+ }
+ }
+ }
+
+ // add at least one policy.
+ if (SecurityModeCB.Items.Count == 0)
+ {
+ SecurityModeCB.Items.Add(MessageSecurityMode.None);
+ }
+ }
+
+ // set the current value.
+ int index = SecurityModeCB.Items.IndexOf(currentMode);
+
+ if (index == -1)
+ {
+ index = 0;
+ }
+
+ SecurityModeCB.SelectedIndex = index;
+ }
+
+ ///
+ /// Initializes the security policies dropdown.
+ ///
+ private void InitializeSecurityPolicies(EndpointDescriptionCollection endpoints)
+ {
+ // filter by the current protocol.
+ Protocol currentProtocol = (Protocol)ProtocolCB.SelectedItem;
+
+ // filter by the current security mode.
+ MessageSecurityMode currentMode = MessageSecurityMode.None;
+
+ if (SecurityModeCB.SelectedIndex != -1)
+ {
+ currentMode = (MessageSecurityMode)SecurityModeCB.SelectedItem;
+ }
+
+ // preserve the existing value.
+ string currentPolicy = (string)SecurityPolicyCB.SelectedItem;
+
+ SecurityPolicyCB.Items.Clear();
+
+ // set all available security policies.
+ if (m_showAllOptions)
+ {
+ var securityPolicies = SecurityPolicies.GetDisplayNames();
+ foreach (var policy in securityPolicies)
+ {
+ SecurityPolicyCB.Items.Add(policy);
+ }
+ }
+
+ // find all unique security policies.
+ else
+ {
+ if (endpoints != null)
+ {
+ foreach (EndpointDescription endpoint in endpoints)
+ {
+ Uri url = Utils.ParseUri(endpoint.EndpointUrl);
+
+ if ((url != null) && (currentProtocol != null))
+ {
+ if (!currentProtocol.Matches(url))
+ {
+ continue;
+ }
+
+ if (currentMode != endpoint.SecurityMode)
+ {
+ continue;
+ }
+
+ string policyName = SecurityPolicies.GetDisplayName(endpoint.SecurityPolicyUri);
+
+ if (policyName != null)
+ {
+ int existingIndex = SecurityPolicyCB.FindStringExact(policyName);
+
+ if (existingIndex == -1)
+ {
+ SecurityPolicyCB.Items.Add(policyName);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // add at least one policy.
+ if (SecurityPolicyCB.Items.Count == 0)
+ {
+ SecurityPolicyCB.Items.Add(SecurityPolicies.GetDisplayName(SecurityPolicies.None));
+ }
+
+ // set the current value.
+ int index = 0;
+
+ if (!String.IsNullOrEmpty(currentPolicy))
+ {
+ index = SecurityPolicyCB.FindStringExact(currentPolicy);
+
+ if (index == -1)
+ {
+ index = 0;
+ }
+ }
+
+ SecurityPolicyCB.SelectedIndex = index;
+ }
+
+ ///
+ /// Initializes the message encodings dropdown.
+ ///
+ private void InitializeEncodings(EndpointDescriptionCollection endpoints, EndpointDescription endpoint)
+ {
+ // preserve the existing value.
+ Encoding currentEncoding = Encoding.Default;
+
+ if (EncodingCB.SelectedIndex != -1)
+ {
+ currentEncoding = (Encoding)EncodingCB.SelectedItem;
+ }
+
+ EncodingCB.Items.Clear();
+
+ if (endpoint != null)
+ {
+ Protocol protocol = new Protocol(endpoint);
+ String securityPolicy = SecurityPolicies.GetDisplayName(endpoint.SecurityPolicyUri);
+
+ foreach (EndpointDescription endpointDescription in endpoints)
+ {
+ if ((protocol.Matches(Utils.ParseUri(endpointDescription.EndpointUrl))) &&
+ (endpoint.SecurityMode == endpointDescription.SecurityMode) &&
+ (securityPolicy == SecurityPolicies.GetDisplayName(endpointDescription.SecurityPolicyUri)))
+ {
+ switch (endpointDescription.EncodingSupport)
+ {
+ case BinaryEncodingSupport.None:
+ {
+ if (!EncodingCB.Items.Contains(Encoding.Xml))
+ {
+ EncodingCB.Items.Add(Encoding.Xml);
+ }
+ break;
+ }
+
+ case BinaryEncodingSupport.Required:
+ {
+ if (!EncodingCB.Items.Contains(Encoding.Binary))
+ {
+ EncodingCB.Items.Add(Encoding.Binary);
+ }
+ break;
+ }
+
+ case BinaryEncodingSupport.Optional:
+ {
+ if (!EncodingCB.Items.Contains(Encoding.Binary))
+ {
+ EncodingCB.Items.Add(Encoding.Binary);
+ }
+ if (!EncodingCB.Items.Contains(Encoding.Xml))
+ {
+ EncodingCB.Items.Add(Encoding.Xml);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // add at least one encoding.
+ if (EncodingCB.Items.Count == 0)
+ {
+ EncodingCB.Items.Add(Encoding.Default);
+ }
+
+ // set the current value.
+ int index = EncodingCB.Items.IndexOf(currentEncoding);
+
+ if (index == -1)
+ {
+ index = 0;
+ }
+
+ EncodingCB.SelectedIndex = index;
+ }
+
+ private class UserTokenItem
+ {
+ public UserTokenPolicy Policy;
+
+ public UserTokenItem(UserTokenPolicy policy)
+ {
+ Policy = policy;
+ }
+
+ public UserTokenItem(UserTokenType tokenType)
+ {
+ Policy = new UserTokenPolicy(tokenType);
+ }
+
+ public override string ToString()
+ {
+ if (Policy != null)
+ {
+ if (String.IsNullOrEmpty(Policy.PolicyId))
+ {
+ return Policy.TokenType.ToString();
+ }
+
+ return Utils.Format("{0} [{1}]", Policy.TokenType, Policy.PolicyId);
+ }
+
+ return UserTokenType.Anonymous.ToString();
+ }
+ }
+
+ ///
+ /// Initializes the endpoint list control.
+ ///
+ private void InitializeEndpointList(List endpoints)
+ {
+ EndpointListLB.Items.Clear();
+
+ foreach (EndpointDescriptionString endpointString in endpoints)
+ {
+ EndpointListLB.Items.Add(endpointString);
+ }
+ }
+
+ private void SelectCorrespondingEndpointFromList(EndpointDescription endpoint)
+ {
+ if (!m_selecting)
+ {
+ int index = -1;
+
+ // try to match endpoint description id
+ if (endpoint != null)
+ {
+ for (int ii = 0; ii < EndpointListLB.Items.Count; ii++)
+ {
+ if (endpoint == ((EndpointDescriptionString)EndpointListLB.Items[ii]).EndpointDescription)
+ {
+ index = ii;
+ break;
+ }
+ }
+ }
+
+ EndpointListLB.SelectedIndex = index;
+ }
+ }
+
+ ///
+ /// Attempts fetch the list of servers from the discovery server.
+ ///
+ private void OnDiscoverEndpoints(object state)
+ {
+ int discoverCount = m_discoverCount;
+
+ // do nothing if a valid list is not provided.
+ ApplicationDescription server = state as ApplicationDescription;
+
+ if (server == null)
+ {
+ return;
+
+ }
+
+ OnUpdateStatus(new Tuple("Attempting to read latest configuration options from server.", StatusType.Ok));
+
+ String discoveryMessage = String.Empty;
+
+ // process each url.
+ foreach (string discoveryUrl in server.DiscoveryUrls)
+ {
+ Uri url = Utils.ParseUri(discoveryUrl);
+
+ if (url != null)
+ {
+ if (DiscoverEndpoints(url, out discoveryMessage))
+ {
+ m_discoverySucceeded = true;
+ m_discoveryUrl = url;
+ OnUpdateStatus(new Tuple("Configuration options are up to date.", StatusType.Ok));
+ return;
+ }
+
+ // check if another discover operation has started.
+ if (discoverCount != m_discoverCount)
+ {
+ return;
+ }
+ }
+ }
+
+ OnUpdateEndpoints(m_availableEndpoints);
+ OnUpdateStatus(new Tuple("Warning: Configuration options may not be correct because the server is not available (" + discoveryMessage + ").", StatusType.Warning));
+ }
+
+ ///
+ /// Fetches the servers from the discovery server.
+ ///
+ private bool DiscoverEndpoints(Uri discoveryUrl, out String message)
+ {
+ // use a short timeout.
+ EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
+ endpointConfiguration.OperationTimeout = m_discoveryTimeout;
+
+ DiscoveryClient client = DiscoveryClient.Create(
+ discoveryUrl,
+ EndpointConfiguration.Create(m_configuration),
+ m_configuration);
+
+ try
+ {
+ EndpointDescriptionCollection endpoints = client.GetEndpoints(null);
+ OnUpdateEndpoints(endpoints);
+ message = String.Empty;
+ return true;
+ }
+ catch (Exception e)
+ {
+ Utils.Trace("Could not fetch endpoints from url: {0}. Reason={1}", discoveryUrl, e.Message);
+ message = e.Message;
+ return false;
+ }
+ finally
+ {
+ client.Close();
+ }
+ }
+
+ ///
+ /// Updates the status displayed in the dialog.
+ ///
+ private void OnUpdateStatus(object status)
+ {
+ if (this.InvokeRequired)
+ {
+ this.BeginInvoke(new WaitCallback(OnUpdateStatus), status);
+ return;
+ }
+
+ Tuple statusTuple = status as Tuple;
+ m_statusObject.SetStatus(StatusChannel.Discovery, statusTuple.Item1, statusTuple.Item2);
+ UpdateStatus();
+ }
+
+ ///
+ /// Updates the list of servers displayed in the control.
+ ///
+ private void OnUpdateEndpoints(object state)
+ {
+ if (this.InvokeRequired)
+ {
+ this.BeginInvoke(new WaitCallback(OnUpdateEndpoints), state);
+ return;
+ }
+
+ try
+ {
+ // get the updated descriptions.
+ EndpointDescriptionCollection endpoints = state as EndpointDescriptionCollection;
+
+ if (endpoints == null)
+ {
+ m_showAllOptions = true;
+ InitializeProtocols(m_availableEndpoints);
+ }
+
+ else
+ {
+ m_showAllOptions = false;
+
+ m_availableEndpoints = endpoints;
+ BuildEndpointDescriptionStrings(m_availableEndpoints);
+
+ if (endpoints.Count > 0)
+ {
+ m_currentDescription = endpoints[0];
+ }
+
+ // initializing the protocol will trigger an update to all other controls.
+ InitializeProtocols(m_availableEndpoints);
+
+ // select the best security mode.
+ MessageSecurityMode bestMode = MessageSecurityMode.Invalid;
+
+ foreach (MessageSecurityMode securityMode in SecurityModeCB.Items)
+ {
+ if (securityMode > bestMode)
+ {
+ bestMode = securityMode;
+ }
+ }
+
+ SecurityModeCB.SelectedItem = bestMode;
+
+ // select the best encoding.
+ Encoding bestEncoding = Encoding.Default;
+
+ foreach (Encoding encoding in EncodingCB.Items)
+ {
+ if (encoding > bestEncoding)
+ {
+ bestEncoding = encoding;
+ }
+ }
+
+ EncodingCB.SelectedItem = bestEncoding;
+ }
+
+ if (m_endpoint != null)
+ {
+ Uri url = m_endpoint.EndpointUrl;
+
+ foreach (Protocol protocol in ProtocolCB.Items)
+ {
+ if (protocol.Matches(url))
+ {
+ ProtocolCB.SelectedItem = protocol;
+ break;
+ }
+ }
+
+ foreach (MessageSecurityMode securityMode in SecurityModeCB.Items)
+ {
+ if (securityMode == m_endpoint.Description.SecurityMode)
+ {
+ SecurityModeCB.SelectedItem = securityMode;
+ break;
+ }
+ }
+
+ foreach (string securityPolicy in SecurityPolicyCB.Items)
+ {
+ if (securityPolicy == m_endpoint.Description.SecurityPolicyUri)
+ {
+ SecurityPolicyCB.SelectedItem = securityPolicy;
+ break;
+ }
+ }
+
+ foreach (Encoding encoding in EncodingCB.Items)
+ {
+ if (encoding == Encoding.Binary && m_endpoint.Configuration.UseBinaryEncoding)
+ {
+ EncodingCB.SelectedItem = encoding;
+ break;
+ }
+
+ if (encoding == Encoding.Xml && !m_endpoint.Configuration.UseBinaryEncoding)
+ {
+ EncodingCB.SelectedItem = encoding;
+ break;
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Utils.Trace(e, "Unexpected error updating endpoints.");
+ }
+ }
+
+ ///
+ /// Creates the endpoint description from current selections.
+ ///
+ private EndpointDescription CreateDescriptionFromSelections()
+ {
+ Protocol currentProtocol = (Protocol)ProtocolCB.SelectedItem;
+
+ EndpointDescription endpoint = null;
+
+ for (int ii = 0; ii < m_availableEndpoints.Count; ii++)
+ {
+ Uri url = Utils.ParseUri(m_availableEndpoints[ii].EndpointUrl);
+
+ if (url == null)
+ {
+ continue;
+ }
+
+ if (endpoint == null)
+ {
+ endpoint = m_availableEndpoints[ii];
+ }
+
+ if (currentProtocol.Matches(url))
+ {
+ endpoint = m_availableEndpoints[ii];
+ break;
+ }
+ }
+
+ UriBuilder builder = null;
+ string scheme = Utils.UriSchemeOpcTcp;
+
+ if (currentProtocol != null && currentProtocol.Url != null)
+ {
+ scheme = currentProtocol.Url.Scheme;
+ }
+
+ if (endpoint == null)
+ {
+ builder = new UriBuilder();
+ builder.Host = "localhost";
+
+ if (scheme == Utils.UriSchemeOpcTcp)
+ {
+ builder.Port = Utils.UaTcpDefaultPort;
+ }
+ }
+ else
+ {
+ builder = new UriBuilder(endpoint.EndpointUrl);
+ }
+
+ builder.Scheme = scheme;
+
+ endpoint = new EndpointDescription();
+ endpoint.EndpointUrl = builder.ToString();
+ endpoint.SecurityMode = (MessageSecurityMode)SecurityModeCB.SelectedItem;
+ endpoint.SecurityPolicyUri = SecurityPolicies.GetUri((string)SecurityPolicyCB.SelectedItem);
+ endpoint.Server.ApplicationName = endpoint.EndpointUrl;
+ endpoint.Server.ApplicationType = ApplicationType.Server;
+ endpoint.Server.ApplicationUri = endpoint.EndpointUrl;
+
+ return endpoint;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // check that discover has completed.
+ if (!m_discoverySucceeded)
+ {
+ DialogResult result = MessageBox.Show(
+ "Endpoint information may be out of date because the discovery process has not completed. Continue anyways?",
+ this.Text,
+ MessageBoxButtons.YesNo,
+ MessageBoxIcon.Warning);
+
+ if (result != DialogResult.Yes)
+ {
+ return;
+ }
+ }
+
+ EndpointConfiguration configuration = m_endpointConfiguration;
+
+ if (configuration == null)
+ {
+ configuration = EndpointConfiguration.Create(m_configuration);
+ }
+
+ if (m_currentDescription == null)
+ {
+ m_currentDescription = CreateDescriptionFromSelections();
+ }
+
+ // the discovery endpoint should always be on the same machine as the server.
+ // if there is a mismatch it is likely because the server has multiple addresses
+ // and was not configured to return the current address to the client.
+ // The code automatically updates the domain in the url.
+ Uri endpointUrl = Utils.ParseUri(m_currentDescription.EndpointUrl);
+
+ if (m_discoverySucceeded)
+ {
+ if (!Utils.AreDomainsEqual(endpointUrl, m_discoveryUrl))
+ {
+ UriBuilder url = new UriBuilder(endpointUrl);
+
+ url.Host = m_discoveryUrl.DnsSafeHost;
+
+ if (url.Scheme == m_discoveryUrl.Scheme)
+ {
+ url.Port = m_discoveryUrl.Port;
+ }
+
+ endpointUrl = url.Uri;
+
+ m_currentDescription.EndpointUrl = endpointUrl.ToString();
+ }
+ }
+
+ // set the encoding.
+ Encoding encoding = (Encoding)EncodingCB.SelectedItem;
+ configuration.UseBinaryEncoding = encoding != Encoding.Xml;
+
+ if (m_endpoint == null)
+ {
+ m_endpoint = new ConfiguredEndpoint(null, m_currentDescription, configuration);
+ }
+ else
+ {
+ m_endpoint.Update(m_currentDescription);
+ m_endpoint.Update(configuration);
+ }
+
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ProtocolCB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ InitializeSecurityModes(m_availableEndpoints);
+
+ if (!m_updating)
+ {
+ try
+ {
+ m_updating = true;
+
+ // update current description.
+ m_currentDescription = FindBestEndpointDescription(m_availableEndpoints);
+
+ InitializeEncodings(m_availableEndpoints, m_currentDescription);
+ SelectCorrespondingEndpointFromList(m_currentDescription);
+ }
+ finally
+ {
+ m_updating = false;
+ }
+ }
+
+ if (ProtocolCB.SelectedItem != null)
+ {
+ if (((Protocol)ProtocolCB.SelectedItem).Url.DnsSafeHost != m_endpoint.EndpointUrl.DnsSafeHost)
+ {
+ m_statusObject.SetStatus(StatusChannel.SelectedProtocol, "Warning: Selected Endpoint hostname is different than initial hostname.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.SelectedProtocol);
+ }
+ }
+ else
+ {
+ m_statusObject.SetStatus(StatusChannel.SelectedProtocol, "Error: Selected Protocol is invalid.", StatusType.Warning);
+ }
+
+ UpdateStatus();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void SecurityModeCB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ InitializeSecurityPolicies(m_availableEndpoints);
+
+ if (!m_updating)
+ {
+ try
+ {
+ m_updating = true;
+
+ // update current description.
+ m_currentDescription = FindBestEndpointDescription(m_availableEndpoints);
+
+ InitializeEncodings(m_availableEndpoints, m_currentDescription);
+ SelectCorrespondingEndpointFromList(m_currentDescription);
+ }
+ finally
+ {
+ m_updating = false;
+ }
+ }
+
+ if (SecurityModeCB.SelectedItem != null)
+ {
+ if ((((MessageSecurityMode)SecurityModeCB.SelectedItem) == MessageSecurityMode.None) &&
+ (ProtocolCB.SelectedItem != null) && (((Protocol)ProtocolCB.SelectedItem).ToString().IndexOf("https") != 0))
+ {
+ m_statusObject.SetStatus(StatusChannel.SelectedSecurityMode, "Warning: Selected Endpoint has no security.", StatusType.Warning);
+ }
+ else if (((MessageSecurityMode)SecurityModeCB.SelectedItem) == MessageSecurityMode.Invalid)
+ {
+ m_statusObject.SetStatus(StatusChannel.SelectedSecurityMode, "Error: Selected Endpoint Security Mode is unsupported.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.SelectedSecurityMode);
+ }
+ }
+ else
+ {
+ m_statusObject.SetStatus(StatusChannel.SelectedSecurityMode, "Error: Selected Endpoint Security Mode is invalid.", StatusType.Warning);
+ }
+
+ UpdateStatus();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void SecurityPolicyCB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ if (!m_updating)
+ {
+ try
+ {
+ m_updating = true;
+
+ // update current description.
+ m_currentDescription = FindBestEndpointDescription(m_availableEndpoints);
+
+ InitializeEncodings(m_availableEndpoints, m_currentDescription);
+ SelectCorrespondingEndpointFromList(m_currentDescription);
+ }
+ finally
+ {
+ m_updating = false;
+ }
+ }
+
+ if (SecurityPolicyCB.SelectedItem != null)
+ {
+ m_statusObject.ClearStatus(StatusChannel.SelectedSecurityPolicy);
+ }
+ else
+ {
+ m_statusObject.SetStatus(StatusChannel.SelectedSecurityPolicy, "Error: Selected Security Policy is invalid.", StatusType.Warning);
+ }
+
+ UpdateStatus();
+
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void EndpointListLB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (!m_updating)
+ {
+ try
+ {
+ m_updating = true;
+ m_selecting = true;
+
+ int selectedIndex = EndpointListLB.SelectedIndex;
+
+ if (selectedIndex != -1)
+ {
+ EndpointDescriptionString selection = (EndpointDescriptionString)EndpointListLB.SelectedItem;
+
+ int index = -1;
+
+ for (int i = 0; i < ProtocolCB.Items.Count; ++i)
+ {
+ if (((Protocol)ProtocolCB.Items[i]).ToString() == selection.Protocol.ToString())
+ {
+ index = i;
+ break;
+ }
+ }
+
+ ProtocolCB.SelectedIndex = index;
+
+ InitializeSecurityModes(m_availableEndpoints);
+
+ m_currentDescription = m_availableEndpoints[selectedIndex];
+
+ InitializeEncodings(m_availableEndpoints, m_currentDescription);
+
+ index = -1;
+
+ for (int i = 0; i < SecurityModeCB.Items.Count; ++i)
+ {
+ if ((MessageSecurityMode)SecurityModeCB.Items[i] == selection.MessageSecurityMode)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ SecurityModeCB.SelectedIndex = index;
+
+ index = -1;
+
+ for (int i = 0; i < SecurityPolicyCB.Items.Count; ++i)
+ {
+ if ((string)SecurityPolicyCB.Items[i] == selection.CurrentPolicy)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ SecurityPolicyCB.SelectedIndex = index;
+
+ index = -1;
+
+ for (int i = 0; i < EncodingCB.Items.Count; ++i)
+ {
+ if ((Encoding)EncodingCB.Items[i] == selection.Encoding)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ EncodingCB.SelectedIndex = index;
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ finally
+ {
+ m_updating = false;
+ m_selecting = false;
+ }
+ }
+
+ UpdateAdvancedEndpointInformation();
+ }
+
+ ///
+ /// Updates advanced endpoint information.
+ ///
+ private void UpdateAdvancedEndpointInformation()
+ {
+ try
+ {
+ ApplicationNameTB.Text = String.Empty;
+ ApplicationTypeTB.Text = String.Empty;
+ ApplicationUriTB.Text = String.Empty;
+ ProductUriTB.Text = String.Empty;
+ GatewayServerUriTB.Text = String.Empty;
+ DiscoveryProfileUriTB.Text = String.Empty;
+ TransportProfileUriTB.Text = String.Empty;
+ UserSecurityPoliciesTB.Text = String.Empty;
+ SecurityLevelTB.Text = String.Empty;
+
+ if (m_currentDescription != null)
+ {
+ UserSecurityPoliciesTB.Text = "Anonymous";
+
+ if (m_currentDescription.Server != null)
+ {
+ if (m_currentDescription.Server.ApplicationName != null)
+ {
+ ApplicationNameTB.Text = m_currentDescription.Server.ApplicationName.ToString();
+ }
+
+ ApplicationTypeTB.Text = m_currentDescription.Server.ApplicationType.ToString();
+ ApplicationUriTB.Text = m_currentDescription.Server.ApplicationUri;
+ ProductUriTB.Text = m_currentDescription.Server.ProductUri;
+ GatewayServerUriTB.Text = m_currentDescription.Server.GatewayServerUri;
+ DiscoveryProfileUriTB.Text = m_currentDescription.Server.DiscoveryProfileUri;
+ }
+
+ SecurityLevelTB.Text = m_currentDescription.SecurityLevel.ToString();
+ TransportProfileUriTB.Text = m_currentDescription.TransportProfileUri;
+
+ if (m_currentDescription.UserIdentityTokens.Count > 0)
+ {
+ UserSecurityPoliciesTB.Text = String.Join(", ", m_currentDescription.UserIdentityTokens);
+ }
+ }
+
+ UpdateStatus();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ ///
+ /// Updates the StatusTB text and color.
+ /// Also enables/disables the OK button, should any error occurr (unsupported stuff etc).
+ ///
+ private void UpdateStatus()
+ {
+ try
+ {
+ if ((m_currentDescription != null) && (m_currentDescription.Server != null))
+ {
+ m_statusObject.ClearStatus(StatusChannel.Server);
+
+ if (m_currentDescription.Server.ApplicationType == ApplicationType.Client)
+ {
+ m_statusObject.SetStatus(StatusChannel.ApplicationType, "Warning: Application type is unsupported.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.ApplicationType);
+ }
+
+ if (string.IsNullOrEmpty(m_currentDescription.Server.ApplicationUri))
+ {
+ m_statusObject.SetStatus(StatusChannel.ApplicationUri, "Warning: Application URI is missing.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.ApplicationUri);
+ }
+
+ if (string.IsNullOrEmpty(m_currentDescription.TransportProfileUri))
+ {
+ m_statusObject.SetStatus(StatusChannel.TransportProfileUri, "Warning: Transport Profile URI is missing.", StatusType.Warning);
+ }
+ else if (Utils.ParseUri(m_currentDescription.TransportProfileUri) == null)
+ {
+ m_statusObject.SetStatus(StatusChannel.TransportProfileUri, "Warning: Transport Profile URI is invalid.", StatusType.Warning);
+ }
+
+ if ((m_currentDescription.Server.DiscoveryUrls == null) || (m_currentDescription.Server.DiscoveryUrls.Count == 0))
+ {
+ m_statusObject.SetStatus(StatusChannel.DiscoveryURLs, "Warning: Discovery URLs are missing.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.DiscoveryURLs);
+ }
+
+ if ((m_currentDescription.ServerCertificate != null) && (m_currentDescription.ServerCertificate.Length > 0))
+ {
+ X509Certificate2 serverCertificate = new X509Certificate2(m_currentDescription.ServerCertificate);
+ String certificateApplicationUri = X509Utils.GetApplicationUriFromCertificate(serverCertificate);
+
+ if (certificateApplicationUri != m_currentDescription.Server.ApplicationUri)
+ {
+ m_statusObject.SetStatus(StatusChannel.DifferentCertificate, "Warning: Application URI host different than the certificate host.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.DifferentCertificate);
+ }
+ }
+
+ if (string.IsNullOrEmpty(m_currentDescription.SecurityPolicyUri))
+ {
+ m_statusObject.SetStatus(StatusChannel.SecurityPolicyUri, "Error: Security Policy URI is missing.", StatusType.Warning);
+ }
+ else if (string.IsNullOrEmpty(SecurityPolicies.GetDisplayName(m_currentDescription.SecurityPolicyUri)))
+ {
+ m_statusObject.SetStatus(StatusChannel.SecurityPolicyUri, "Error: Security Policy URI is invalid.", StatusType.Warning);
+ }
+ else
+ {
+ m_statusObject.ClearStatus(StatusChannel.SecurityPolicyUri);
+ }
+ }
+ else
+ {
+ m_statusObject.SetStatus(StatusChannel.Server, "Warning: Server endpoint is invalid.", StatusType.Warning);
+ }
+
+
+ OkBTN.Enabled = true;
+ StatusTB.ForeColor = SystemColors.WindowText;
+ StatusTB.Text = m_statusObject.StatusString;
+
+ if (m_statusObject.StatusType == StatusType.Error)
+ {
+ OkBTN.Enabled = false;
+ StatusTB.ForeColor = Color.Red;
+ }
+ else if (m_statusObject.StatusType == StatusType.Warning)
+ {
+ StatusTB.ForeColor = Color.DarkOrange;
+ }
+
+ // hack for WinForms to update color
+ StatusTB.BackColor = StatusTB.BackColor;
+
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.Designer.cs
new file mode 100644
index 00000000..5c350d3a
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.Designer.cs
@@ -0,0 +1,120 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ConfiguredServerListCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.PopupMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.NewMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.ConfigureMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.DeleteMI = new System.Windows.Forms.ToolStripMenuItem();
+ this.PopupMenu.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ItemsLV
+ //
+ this.ItemsLV.ContextMenuStrip = this.PopupMenu;
+ //
+ // PopupMenu
+ //
+ this.PopupMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.NewMI,
+ this.ConfigureMI,
+ this.DeleteMI});
+ this.PopupMenu.Name = "PopupMenu";
+ this.PopupMenu.Size = new System.Drawing.Size(153, 92);
+ //
+ // NewMI
+ //
+ this.NewMI.Name = "NewMI";
+ this.NewMI.Size = new System.Drawing.Size(152, 22);
+ this.NewMI.Text = "New...";
+ this.NewMI.Click += new System.EventHandler(this.NewMI_Click);
+ //
+ // ConfigureMI
+ //
+ this.ConfigureMI.Name = "ConfigureMI";
+ this.ConfigureMI.Size = new System.Drawing.Size(152, 22);
+ this.ConfigureMI.Text = "Configure...";
+ this.ConfigureMI.Click += new System.EventHandler(this.ConfigureMI_Click);
+ //
+ // DeleteMI
+ //
+ this.DeleteMI.Name = "DeleteMI";
+ this.DeleteMI.Size = new System.Drawing.Size(152, 22);
+ this.DeleteMI.Text = "Delete";
+ this.DeleteMI.Click += new System.EventHandler(this.DeleteMI_Click);
+ //
+ // ConfiguredServerListCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.Name = "ConfiguredServerListCtrl";
+ this.Controls.SetChildIndex(this.ItemsLV, 0);
+ this.PopupMenu.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ContextMenuStrip PopupMenu;
+ private System.Windows.Forms.ToolStripMenuItem NewMI;
+ private System.Windows.Forms.ToolStripMenuItem ConfigureMI;
+ private System.Windows.Forms.ToolStripMenuItem DeleteMI;
+
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.cs
new file mode 100644
index 00000000..5e8891c6
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.cs
@@ -0,0 +1,255 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Threading;
+using System.Reflection;
+
+using Opc.Ua.Client.Controls;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A list of servers.
+ ///
+ public partial class ConfiguredServerListCtrl : Opc.Ua.Client.Controls.BaseListCtrl
+ {
+ #region Constructors
+ ///
+ /// Initalize the control.
+ ///
+ public ConfiguredServerListCtrl()
+ {
+ InitializeComponent();
+ SetColumns(m_ColumnNames);
+ }
+ #endregion
+
+ #region Private Fields
+ // The columns to display in the control.
+ private readonly object[][] m_ColumnNames = new object[][]
+ {
+ new object[] { "Name", HorizontalAlignment.Left, null },
+ new object[] { "Host", HorizontalAlignment.Left, null },
+ new object[] { "Protocol", HorizontalAlignment.Left, null },
+ new object[] { "Security Mode", HorizontalAlignment.Left, null },
+ new object[] { "User Token", HorizontalAlignment.Left, null }
+ };
+
+ private ApplicationConfiguration m_configuration;
+ private ConfiguredEndpointCollection m_endpoints;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays a list of servers in the control.
+ ///
+ public void Initialize(ConfiguredEndpointCollection endpoints, ApplicationConfiguration configuration)
+ {
+ Interlocked.Exchange(ref m_configuration, configuration);
+
+ ItemsLV.Items.Clear();
+
+ m_endpoints = endpoints;
+
+ if (endpoints != null)
+ {
+ foreach (ConfiguredEndpoint endpoint in endpoints.Endpoints)
+ {
+ AddItem(endpoint);
+ }
+ }
+
+ AdjustColumns();
+ }
+ #endregion
+
+ #region Overridden Methods
+ ///
+ /// Enables context menu items.
+ ///
+ protected override void EnableMenuItems(ListViewItem clickedItem)
+ {
+ base.EnableMenuItems(clickedItem);
+
+ NewMI.Enabled = true;
+
+ if (clickedItem != null)
+ {
+ ConfiguredEndpoint endpoint = clickedItem.Tag as ConfiguredEndpoint;
+
+ if (endpoint == null)
+ {
+ return;
+ }
+
+ ConfigureMI.Enabled = true;
+ DeleteMI.Enabled = true;
+ }
+ }
+
+ ///
+ /// Updates an item in the control.
+ ///
+ protected override void UpdateItem(ListViewItem listItem, object item)
+ {
+ ConfiguredEndpoint endpoint = listItem.Tag as ConfiguredEndpoint;
+
+ if (endpoint == null)
+ {
+ base.UpdateItem(listItem, endpoint);
+ return;
+ }
+
+ string hostname = "";
+ string protocol = "";
+
+ Uri uri = endpoint.EndpointUrl;
+
+ if (uri != null)
+ {
+ hostname = uri.DnsSafeHost;
+ protocol = uri.Scheme;
+ }
+
+ listItem.SubItems[0].Text = String.Format("{0}", endpoint.Description.Server.ApplicationName);
+ listItem.SubItems[1].Text = String.Format("{0}", hostname);
+ listItem.SubItems[2].Text = String.Format("{0}", protocol);
+
+ listItem.SubItems[3].Text = String.Format(
+ "{0}/{1}",
+ SecurityPolicies.GetDisplayName(endpoint.Description.SecurityPolicyUri),
+ endpoint.Description.SecurityMode);
+
+ listItem.SubItems[4].Text = "";
+
+ UserTokenPolicy policy = endpoint.SelectedUserTokenPolicy;
+
+ if (policy != null)
+ {
+ StringBuilder buffer = new StringBuilder();
+
+ buffer.Append(policy.TokenType);
+
+ if (endpoint.UserIdentity != null)
+ {
+ buffer.Append("/");
+ buffer.Append(endpoint.UserIdentity);
+ }
+
+ listItem.SubItems[4].Text = buffer.ToString();
+ }
+
+ listItem.ImageKey = GuiUtils.Icons.Process;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void NewMI_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ ApplicationDescription server = new DiscoveredServerListDlg().ShowDialog(null, m_configuration);
+
+ if (server == null)
+ {
+ return;
+ }
+
+ ConfiguredEndpoint endpoint = new ConfiguredServerDlg().ShowDialog(server, m_configuration);
+
+ if (endpoint == null)
+ {
+ return;
+ }
+
+ AddItem(endpoint);
+ AdjustColumns();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ConfigureMI_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ ConfiguredEndpoint endpoint = SelectedTag as ConfiguredEndpoint;
+
+ if (endpoint == null)
+ {
+ return;
+ }
+
+ endpoint = new ConfiguredServerDlg().ShowDialog(endpoint, m_configuration);
+
+ if (endpoint == null)
+ {
+ return;
+ }
+
+ UpdateItem(ItemsLV.SelectedItems[0], endpoint);
+ AdjustColumns();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void DeleteMI_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ ConfiguredEndpoint endpoint = SelectedTag as ConfiguredEndpoint;
+
+ if (endpoint == null)
+ {
+ return;
+ }
+
+ ItemsLV.SelectedItems[0].Remove();
+ AdjustColumns();
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.resx
new file mode 100644
index 00000000..edd3be8a
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListCtrl.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.Designer.cs
new file mode 100644
index 00000000..64c78947
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.Designer.cs
@@ -0,0 +1,149 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ConfiguredServerListDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ServersCTRL = new Opc.Ua.Client.Controls.ConfiguredServerListCtrl();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(2, 353);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(673, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(594, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ServersCTRL);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(2, 2);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(0, 3, 0, 0);
+ this.MainPN.Size = new System.Drawing.Size(673, 351);
+ this.MainPN.TabIndex = 1;
+ //
+ // ServersCTRL
+ //
+ this.ServersCTRL.Cursor = System.Windows.Forms.Cursors.Default;
+ this.ServersCTRL.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ServersCTRL.Instructions = null;
+ this.ServersCTRL.Location = new System.Drawing.Point(0, 3);
+ this.ServersCTRL.Name = "ServersCTRL";
+ this.ServersCTRL.Size = new System.Drawing.Size(673, 348);
+ this.ServersCTRL.TabIndex = 0;
+ this.ServersCTRL.ItemsSelected += new Opc.Ua.Client.Controls.ListItemActionEventHandler(this.ServersCTRL_ItemsSelected);
+ //
+ // ConfiguredServerListDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(677, 384);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "ConfiguredServerListDlg";
+ this.Padding = new System.Windows.Forms.Padding(2, 2, 2, 0);
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Configure Servers";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private ConfiguredServerListCtrl ServersCTRL;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.cs
new file mode 100644
index 00000000..a6da13d3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.cs
@@ -0,0 +1,131 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Allows the user to browse a list of servers.
+ ///
+ public partial class ConfiguredServerListDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes the dialog.
+ ///
+ public ConfiguredServerListDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Private Fields
+ private ConfiguredEndpoint m_endpoint;
+ private ApplicationConfiguration m_configuration;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public ConfiguredEndpoint ShowDialog(ApplicationConfiguration configuration, bool createNew)
+ {
+ m_configuration = configuration;
+ m_endpoint = null;
+
+ // create a default collection if none provided.
+ if (createNew)
+ {
+ ApplicationDescription server = new DiscoveredServerListDlg().ShowDialog(null, m_configuration);
+
+ if (server != null)
+ {
+ return new ConfiguredEndpoint(server, EndpointConfiguration.Create(configuration));
+ }
+
+ return null;
+ }
+
+ ServersCTRL.Initialize(null, configuration);
+
+ OkBTN.Enabled = false;
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_endpoint;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ServersCTRL_ItemsSelected(object sender, ListItemActionEventArgs e)
+ {
+ try
+ {
+ m_endpoint = null;
+
+ foreach (ConfiguredEndpoint server in e.Items)
+ {
+ m_endpoint = server;
+ break;
+ }
+
+ OkBTN.Enabled = m_endpoint != null;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/ConfiguredServerListDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.Designer.cs
new file mode 100644
index 00000000..d340d256
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.Designer.cs
@@ -0,0 +1,73 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class DiscoveredServerListCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // UserAccountListCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.Name = "UserAccountListCtrl";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.cs
new file mode 100644
index 00000000..2a1c3b6c
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.cs
@@ -0,0 +1,325 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Threading;
+
+using Opc.Ua.Client.Controls;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Displays a list of servers.
+ ///
+ public partial class DiscoveredServerListCtrl : Opc.Ua.Client.Controls.BaseListCtrl
+ {
+ #region Constructors
+ ///
+ /// Initalize the control.
+ ///
+ public DiscoveredServerListCtrl()
+ {
+ InitializeComponent();
+ SetColumns(m_ColumnNames);
+ ItemsLV.Sorting = SortOrder.Descending;
+ ItemsLV.MultiSelect = false;
+ }
+ #endregion
+
+ #region Private Fields
+ // The columns to display in the control.
+ private readonly object[][] m_ColumnNames = new object[][]
+ {
+ new object[] { "Name", HorizontalAlignment.Left, null },
+ new object[] { "Type", HorizontalAlignment.Left, null },
+ new object[] { "Host", HorizontalAlignment.Left, null },
+ new object[] { "URI", HorizontalAlignment.Left, null }
+ };
+
+ private ApplicationConfiguration m_configuration;
+ private int m_discoveryTimeout;
+ private int m_discoverCount;
+ private string m_discoveryUrl;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// The timeout in milliseconds to use when discovering servers.
+ ///
+ [System.ComponentModel.DefaultValue(5000)]
+ public int DiscoveryTimeout
+ {
+ get { return m_discoveryTimeout; }
+ set { m_discoveryTimeout = value; }
+ }
+
+ ///
+ /// Gets or sets the discovery URL used to find the servers displayed in the control.
+ ///
+ /// The discovery URL.
+ public string DiscoveryUrl
+ {
+ get { return m_discoveryUrl; }
+ set { m_discoveryUrl = value; }
+ }
+
+ ///
+ /// Displays a list of servers in the control.
+ ///
+ public void Initialize(ConfiguredEndpointCollection endpoints, ApplicationConfiguration configuration)
+ {
+ Interlocked.Exchange(ref m_configuration, configuration);
+
+ ItemsLV.Items.Clear();
+
+ foreach (ApplicationDescription server in endpoints.GetServers())
+ {
+ AddItem(server);
+ }
+
+ AdjustColumns();
+ }
+
+ ///
+ /// Displays a list of servers in the control.
+ ///
+ public void Initialize(string hostname, ApplicationConfiguration configuration)
+ {
+ Interlocked.Exchange(ref m_configuration, configuration);
+
+ ItemsLV.Items.Clear();
+
+ if (String.IsNullOrEmpty(hostname))
+ {
+ hostname = System.Net.Dns.GetHostName();
+ }
+
+ this.Instructions = Utils.Format("Discovering servers on host '{0}'.", hostname);
+ AdjustColumns();
+
+ // get a list of well known discovery urls to use.
+ StringCollection discoveryUrls = null;
+
+ if (configuration != null && configuration.ClientConfiguration != null)
+ {
+ discoveryUrls = configuration.ClientConfiguration.WellKnownDiscoveryUrls;
+ }
+
+ if (discoveryUrls == null || discoveryUrls.Count == 0)
+ {
+ discoveryUrls = new StringCollection(Utils.DiscoveryUrls);
+ }
+
+ // update the urls with the hostname.
+ StringCollection urlsToUse = new StringCollection();
+
+ foreach (string discoveryUrl in discoveryUrls)
+ {
+ urlsToUse.Add(Utils.Format(discoveryUrl, hostname));
+ }
+
+ Interlocked.Increment(ref m_discoverCount);
+ ThreadPool.QueueUserWorkItem(new WaitCallback(OnDiscoverServers), urlsToUse);
+ }
+
+ ///
+ /// Updates the list of servers displayed in the control.
+ ///
+ private void OnUpdateServers(object state)
+ {
+ if (this.InvokeRequired)
+ {
+ this.BeginInvoke(new WaitCallback(OnUpdateServers), state);
+ return;
+ }
+
+ ItemsLV.Items.Clear();
+
+ ApplicationDescriptionCollection servers = state as ApplicationDescriptionCollection;
+
+ if (servers != null)
+ {
+ foreach (ApplicationDescription server in servers)
+ {
+ if (server.ApplicationType == ApplicationType.DiscoveryServer)
+ {
+ continue;
+ }
+
+ AddItem(server);
+ }
+ }
+
+ if (ItemsLV.Items.Count == 0)
+ {
+ this.Instructions = Utils.Format("No servers to display.");
+ }
+
+ AdjustColumns();
+ }
+
+ ///
+ /// Attempts fetch the list of servers from the discovery server.
+ ///
+ private void OnDiscoverServers(object state)
+ {
+ try
+ {
+ int discoverCount = m_discoverCount;
+
+ // do nothing if a valid list is not provided.
+ IList discoveryUrls = state as IList;
+
+ if (discoveryUrls == null)
+ {
+ return;
+ }
+
+ // process each url.
+ foreach (string discoveryUrl in discoveryUrls)
+ {
+ Uri url = Utils.ParseUri(discoveryUrl);
+
+ if (url != null)
+ {
+ if (DiscoverServers(url))
+ {
+ return;
+ }
+
+ // check if another discover operation has started.
+ if (discoverCount != m_discoverCount)
+ {
+ return;
+ }
+ }
+ }
+
+ // display empty list.
+ OnUpdateServers(null);
+ }
+ catch (Exception e)
+ {
+ Utils.Trace(e, "Unexpected error discovering servers.");
+ }
+ }
+
+ ///
+ /// Fetches the servers from the discovery server.
+ ///
+ private bool DiscoverServers(Uri discoveryUrl)
+ {
+ // use a short timeout.
+ EndpointConfiguration configuration = EndpointConfiguration.Create(m_configuration);
+ configuration.OperationTimeout = m_discoveryTimeout;
+
+ DiscoveryClient client = null;
+
+ try
+ {
+ client = DiscoveryClient.Create(
+ discoveryUrl,
+ BindingFactory.Create(m_configuration, m_configuration.CreateMessageContext()),
+ EndpointConfiguration.Create(m_configuration));
+
+ ApplicationDescriptionCollection servers = client.FindServers(null);
+ m_discoveryUrl = discoveryUrl.ToString();
+ OnUpdateServers(servers);
+ return true;
+ }
+ catch (Exception e)
+ {
+ Utils.Trace("DISCOVERY ERROR - Could not fetch servers from url: {0}. Error=({2}){1}", discoveryUrl, e.Message, e.GetType());
+ return false;
+ }
+ finally
+ {
+ if (client != null)
+ {
+ client.Close();
+ }
+ }
+ }
+ #endregion
+
+ #region Overridden Methods
+ ///
+ /// Updates an item in the control.
+ ///
+ protected override void UpdateItem(ListViewItem listItem, object item)
+ {
+ ApplicationDescription server = listItem.Tag as ApplicationDescription;
+
+ if (server == null)
+ {
+ base.UpdateItem(listItem, server);
+ return;
+ }
+
+ string hostname = "";
+
+ // extract host from application uri.
+ Uri uri = Utils.ParseUri(server.ApplicationUri);
+
+ if (uri != null)
+ {
+ hostname = uri.DnsSafeHost;
+ }
+
+ // get the host name from the discovery urls.
+ if (String.IsNullOrEmpty(hostname))
+ {
+ foreach (string discoveryUrl in server.DiscoveryUrls)
+ {
+ Uri url = Utils.ParseUri(discoveryUrl);
+
+ if (url != null)
+ {
+ hostname = url.DnsSafeHost;
+ break;
+ }
+ }
+ }
+
+ listItem.SubItems[0].Text = String.Format("{0}", server.ApplicationName);
+ listItem.SubItems[1].Text = String.Format("{0}", server.ApplicationType);
+ listItem.SubItems[2].Text = String.Format("{0}", hostname);
+ listItem.SubItems[3].Text = String.Format("{0}", server.ApplicationUri);
+
+ listItem.ImageKey = GuiUtils.Icons.Service;
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.Designer.cs
new file mode 100644
index 00000000..53e87cdf
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.Designer.cs
@@ -0,0 +1,197 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class DiscoveredServerListDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ServersCTRL = new Opc.Ua.Client.Controls.DiscoveredServerListCtrl();
+ this.TopPN = new System.Windows.Forms.Panel();
+ this.HostNameLB = new System.Windows.Forms.Label();
+ this.HostNameCTRL = new Opc.Ua.Client.Controls.SelectHostCtrl();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.TopPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(2, 353);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(673, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(594, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.ServersCTRL);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(2, 23);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(0, 3, 0, 0);
+ this.MainPN.Size = new System.Drawing.Size(673, 330);
+ this.MainPN.TabIndex = 2;
+ //
+ // ServersCTRL
+ //
+ this.ServersCTRL.Cursor = System.Windows.Forms.Cursors.Default;
+ this.ServersCTRL.DiscoveryTimeout = 0;
+ this.ServersCTRL.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ServersCTRL.Instructions = null;
+ this.ServersCTRL.Location = new System.Drawing.Point(0, 3);
+ this.ServersCTRL.Name = "ServersCTRL";
+ this.ServersCTRL.Size = new System.Drawing.Size(673, 327);
+ this.ServersCTRL.TabIndex = 0;
+ this.ServersCTRL.ItemsPicked += new Opc.Ua.Client.Controls.ListItemActionEventHandler(this.ServersCTRL_ItemsPicked);
+ this.ServersCTRL.ItemsSelected += new Opc.Ua.Client.Controls.ListItemActionEventHandler(this.ServersCTRL_ItemsSelected);
+ //
+ // TopPN
+ //
+ this.TopPN.Controls.Add(this.HostNameLB);
+ this.TopPN.Controls.Add(this.HostNameCTRL);
+ this.TopPN.Dock = System.Windows.Forms.DockStyle.Top;
+ this.TopPN.Location = new System.Drawing.Point(2, 2);
+ this.TopPN.Name = "TopPN";
+ this.TopPN.Size = new System.Drawing.Size(673, 21);
+ this.TopPN.TabIndex = 1;
+ //
+ // HostNameLB
+ //
+ this.HostNameLB.AutoSize = true;
+ this.HostNameLB.Location = new System.Drawing.Point(0, 4);
+ this.HostNameLB.Name = "HostNameLB";
+ this.HostNameLB.Size = new System.Drawing.Size(60, 13);
+ this.HostNameLB.TabIndex = 0;
+ this.HostNameLB.Text = "Host Name";
+ this.HostNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // HostNameCTRL
+ //
+ this.HostNameCTRL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.HostNameCTRL.CommandText = "Discover";
+ this.HostNameCTRL.Location = new System.Drawing.Point(63, 0);
+ this.HostNameCTRL.Margin = new System.Windows.Forms.Padding(0);
+ this.HostNameCTRL.MaximumSize = new System.Drawing.Size(4096, 24);
+ this.HostNameCTRL.MinimumSize = new System.Drawing.Size(400, 21);
+ this.HostNameCTRL.Name = "HostNameCTRL";
+ this.HostNameCTRL.Padding = new System.Windows.Forms.Padding(2, 0, 0, 0);
+ this.HostNameCTRL.Size = new System.Drawing.Size(610, 21);
+ this.HostNameCTRL.TabIndex = 1;
+ this.HostNameCTRL.HostConnected += new System.EventHandler(this.HostNameCTRL_HostConnected);
+ this.HostNameCTRL.HostSelected += new System.EventHandler(this.HostNameCTRL_HostSelected);
+ //
+ // DiscoveredServerListDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(677, 384);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.TopPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.MaximumSize = new System.Drawing.Size(1024, 1024);
+ this.MinimumSize = new System.Drawing.Size(300, 300);
+ this.Name = "DiscoveredServerListDlg";
+ this.Padding = new System.Windows.Forms.Padding(2, 2, 2, 0);
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Discover Servers";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.TopPN.ResumeLayout(false);
+ this.TopPN.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private DiscoveredServerListCtrl ServersCTRL;
+ private SelectHostCtrl HostNameCTRL;
+ private System.Windows.Forms.Panel TopPN;
+ private System.Windows.Forms.Label HostNameLB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.cs
new file mode 100644
index 00000000..ed9e0417
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.cs
@@ -0,0 +1,182 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Allows the user to browse a list of servers.
+ ///
+ public partial class DiscoveredServerListDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes the dialog.
+ ///
+ public DiscoveredServerListDlg()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private string m_hostname;
+ private ApplicationDescription m_server;
+ private ApplicationConfiguration m_configuration;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public ApplicationDescription ShowDialog(string hostname, ApplicationConfiguration configuration)
+ {
+ m_configuration = configuration;
+
+ if (String.IsNullOrEmpty(hostname))
+ {
+ hostname = System.Net.Dns.GetHostName();
+ }
+
+ m_hostname = hostname;
+ List hostnames = new List();
+
+ HostNameCTRL.Initialize(hostname, hostnames);
+ ServersCTRL.Initialize(hostname, configuration);
+
+ OkBTN.Enabled = false;
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_server;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void HostNameCTRL_HostSelected(object sender, SelectHostCtrlEventArgs e)
+ {
+ try
+ {
+ if (m_hostname != e.Hostname)
+ {
+ m_hostname = e.Hostname;
+ ServersCTRL.Initialize(m_hostname, m_configuration);
+ m_server = null;
+ OkBTN.Enabled = false;
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void HostNameCTRL_HostConnected(object sender, SelectHostCtrlEventArgs e)
+ {
+ try
+ {
+ m_hostname = e.Hostname;
+ ServersCTRL.Initialize(m_hostname, m_configuration);
+ m_server = null;
+ OkBTN.Enabled = false;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ServersCTRL_ItemsSelected(object sender, ListItemActionEventArgs e)
+ {
+ try
+ {
+ m_server = null;
+
+ foreach (ApplicationDescription server in e.Items)
+ {
+ m_server = server;
+ break;
+ }
+
+ OkBTN.Enabled = m_server != null;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ServersCTRL_ItemsPicked(object sender, ListItemActionEventArgs e)
+ {
+ try
+ {
+ m_server = null;
+
+ foreach (ApplicationDescription server in e.Items)
+ {
+ m_server = server;
+ break;
+ }
+
+ if (m_server != null)
+ {
+ DialogResult = DialogResult.OK;
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/DiscoveredServerListDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.Designer.cs
new file mode 100644
index 00000000..4666c60b
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.Designer.cs
@@ -0,0 +1,120 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class EndpointSelectorCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.EndpointCB = new System.Windows.Forms.ComboBox();
+ this.ConnectButton = new System.Windows.Forms.Button();
+ this.ConnectPN = new System.Windows.Forms.Panel();
+ this.ConnectPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // EndpointCB
+ //
+ this.EndpointCB.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
+ this.EndpointCB.FormattingEnabled = true;
+ this.EndpointCB.Location = new System.Drawing.Point(3, 4);
+ this.EndpointCB.Name = "EndpointCB";
+ this.EndpointCB.Size = new System.Drawing.Size(622, 21);
+ this.EndpointCB.TabIndex = 0;
+ this.EndpointCB.SelectedIndexChanged += new System.EventHandler(this.EndpointCB_SelectedIndexChanged);
+ //
+ // ConnectButton
+ //
+ this.ConnectButton.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ConnectButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.ConnectButton.Location = new System.Drawing.Point(3, 3);
+ this.ConnectButton.Name = "ConnectButton";
+ this.ConnectButton.Size = new System.Drawing.Size(102, 22);
+ this.ConnectButton.TabIndex = 1;
+ this.ConnectButton.Text = "Connect";
+ this.ConnectButton.UseVisualStyleBackColor = true;
+ this.ConnectButton.Click += new System.EventHandler(this.ConnectButton_Click);
+ //
+ // ConnectPN
+ //
+ this.ConnectPN.Controls.Add(this.ConnectButton);
+ this.ConnectPN.Dock = System.Windows.Forms.DockStyle.Right;
+ this.ConnectPN.Location = new System.Drawing.Point(626, 0);
+ this.ConnectPN.Name = "ConnectPN";
+ this.ConnectPN.Padding = new System.Windows.Forms.Padding(3);
+ this.ConnectPN.Size = new System.Drawing.Size(108, 28);
+ this.ConnectPN.TabIndex = 2;
+ //
+ // EndpointSelectorCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.ConnectPN);
+ this.Controls.Add(this.EndpointCB);
+ this.MaximumSize = new System.Drawing.Size(2048, 28);
+ this.MinimumSize = new System.Drawing.Size(100, 28);
+ this.Name = "EndpointSelectorCtrl";
+ this.Padding = new System.Windows.Forms.Padding(2, 0, 0, 0);
+ this.Size = new System.Drawing.Size(734, 28);
+ this.ConnectPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ComboBox EndpointCB;
+ private System.Windows.Forms.Button ConnectButton;
+ private System.Windows.Forms.Panel ConnectPN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.cs
new file mode 100644
index 00000000..8a247b9d
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.cs
@@ -0,0 +1,296 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Runtime.Serialization;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A control which displays a list of endpoints
+ ///
+ public partial class EndpointSelectorCtrl : UserControl
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public EndpointSelectorCtrl()
+ {
+ InitializeComponent();
+ }
+
+ #region Private Fields
+ private int m_selectedIndex;
+ private ApplicationConfiguration m_configuration;
+ private ConfiguredEndpointCollection m_endpoints;
+ private event ConnectEndpointEventHandler m_ConnectEndpoint;
+ private event EventHandler m_EndpointsChanged;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Raised when the user presses the connect button.
+ ///
+ public event ConnectEndpointEventHandler ConnectEndpoint
+ {
+ add { m_ConnectEndpoint += value; }
+ remove { m_ConnectEndpoint -= value; }
+ }
+
+ ///
+ /// Raised when the endpoints displayed in the control are changed.
+ ///
+ public event EventHandler EndpointsChanged
+ {
+ add { m_EndpointsChanged += value; }
+ remove { m_EndpointsChanged -= value; }
+ }
+
+ ///
+ /// The endpoint currently displayed in the control.
+ ///
+ public ConfiguredEndpoint SelectedEndpoint
+ {
+ get
+ {
+ ConfiguredEndpoint item = EndpointCB.SelectedItem as ConfiguredEndpoint;
+
+ if (item != null)
+ {
+ return item;
+ }
+
+ if (String.IsNullOrEmpty(EndpointCB.Text))
+ {
+ return null;
+ }
+
+ return m_endpoints.Create(EndpointCB.Text);
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ EndpointCB.Text = null;
+ EndpointCB.SelectedIndex = -1;
+ return;
+ }
+
+ for (int ii = 1; ii < EndpointCB.Items.Count; ii++)
+ {
+ ConfiguredEndpoint item = EndpointCB.Items[ii] as ConfiguredEndpoint;
+
+ if (Object.ReferenceEquals(item, value))
+ {
+ EndpointCB.SelectedItem = item;
+ return;
+ }
+ }
+
+ // must be a new endpoint.
+ m_endpoints.Add(value);
+
+ // raise notification.
+ if (m_EndpointsChanged != null)
+ {
+ m_EndpointsChanged(this, null);
+ }
+
+ EndpointCB.SelectedIndex = EndpointCB.Items.Add(value);
+ }
+ }
+
+ ///
+ /// Initializes the control with a list of endpoints.
+ ///
+ public void Initialize(ConfiguredEndpointCollection endpoints, ApplicationConfiguration configuration)
+ {
+ if (endpoints == null) throw new ArgumentNullException("endpoints");
+
+ m_endpoints = endpoints;
+ m_configuration = configuration;
+
+ EndpointCB.Items.Clear();
+ EndpointCB.SelectedIndex = -1;
+ EndpointCB.Items.Add("");
+
+ if (endpoints != null)
+ {
+ foreach (ConfiguredEndpoint endpoint in m_endpoints.Endpoints)
+ {
+ EndpointCB.Items.Add(endpoint);
+ }
+ }
+
+ if (EndpointCB.Items.Count > 1)
+ {
+ EndpointCB.SelectedIndex = m_selectedIndex = 1;
+ }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void ConnectButton_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // get selected endpoint.
+ ConfiguredEndpoint endpoint = SelectedEndpoint;
+
+ if (endpoint == null)
+ {
+ return;
+ }
+
+ // raise event.
+ if (m_ConnectEndpoint != null)
+ {
+ ConnectEndpointEventArgs args = new ConnectEndpointEventArgs(endpoint, true);
+
+ m_ConnectEndpoint(this, args);
+
+ // save endpoint in drop down.
+ if (args.UpdateControl)
+ {
+ // must update the control because the display text may have changed.
+ Initialize(m_endpoints, m_configuration);
+ SelectedEndpoint = endpoint;
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void EndpointCB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ if (EndpointCB.SelectedIndex != 0)
+ {
+ m_selectedIndex = EndpointCB.SelectedIndex;
+ return;
+ }
+
+ // modify configuration.
+ ConfiguredEndpoint endpoint = new ConfiguredServerListDlg().ShowDialog(m_configuration, true);
+
+ if (endpoint == null)
+ {
+ EndpointCB.SelectedIndex = m_selectedIndex;
+ return;
+ }
+
+ m_endpoints.Add(endpoint);
+
+ // raise notification.
+ if (m_EndpointsChanged != null)
+ {
+ m_EndpointsChanged(this, null);
+ }
+
+ // update dropdown.
+ Initialize(m_endpoints, m_configuration);
+
+ // update selection.
+ for (int ii = 0; ii < m_endpoints.Endpoints.Count; ii++)
+ {
+ if (Object.ReferenceEquals(endpoint, m_endpoints.Endpoints[ii]))
+ {
+ EndpointCB.SelectedIndex = ii+1;
+ break;
+ }
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+
+ #region ConnectEndpointEventArgs Class
+ ///
+ /// Contains arguments for a ConnectEndpoint event.
+ ///
+ public class ConnectEndpointEventArgs : EventArgs
+ {
+ ///
+ /// Initializes the object.
+ ///
+ public ConnectEndpointEventArgs(ConfiguredEndpoint endpoint, bool updateControl)
+ {
+ m_endpoint = endpoint;
+ m_updateControl = updateControl;
+ }
+
+ ///
+ /// The endpoint selected in the control.
+ ///
+ public ConfiguredEndpoint Endpoint
+ {
+ get { return m_endpoint; }
+ }
+
+ ///
+ /// Whether the endpoint should be saved in the control after the event completes.
+ ///
+ public bool UpdateControl
+ {
+ get { return m_updateControl; }
+ set { m_updateControl = value; }
+ }
+
+ #region Private Fields
+ private ConfiguredEndpoint m_endpoint;
+ private bool m_updateControl;
+ #endregion
+ }
+
+ ///
+ /// The delegate used to receive connect endpoint notifications.
+ ///
+ public delegate void ConnectEndpointEventHandler(object sender, ConnectEndpointEventArgs e);
+ #endregion
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/EndpointSelectorCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.Designer.cs
new file mode 100644
index 00000000..b260b59a
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.Designer.cs
@@ -0,0 +1,73 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class HostListCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // UserAccountListCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.Name = "UserAccountListCtrl";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.cs
new file mode 100644
index 00000000..87c4ff7b
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.cs
@@ -0,0 +1,218 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Threading;
+using System.Net;
+
+using Opc.Ua.Configuration;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A list of hosts.
+ ///
+ public partial class HostListCtrl : Opc.Ua.Client.Controls.BaseListCtrl
+ {
+ #region Constructors
+ ///
+ /// Initalize the control.
+ ///
+ public HostListCtrl()
+ {
+ InitializeComponent();
+ SetColumns(m_ColumnNames);
+ m_enumerator = new HostEnumerator();
+ m_enumerator.HostsDiscovered += new EventHandler(HostEnumerator_HostsDiscovered);
+ }
+ #endregion
+
+ #region Private Fields
+ // The columns to display in the control.
+ private readonly object[][] m_ColumnNames = new object[][]
+ {
+ new object[] { "Name", HorizontalAlignment.Left, null },
+ new object[] { "Addresses", HorizontalAlignment.Left, null }
+ };
+
+ private HostEnumerator m_enumerator;
+ private bool m_waitingForHosts;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays a list of servers in the control.
+ ///
+ public void Initialize(string domain)
+ {
+ ItemsLV.Items.Clear();
+
+ this.Instructions = Utils.Format("Discovering hosts on domain '{0}'.", domain);
+ AdjustColumns();
+
+ m_waitingForHosts = true;
+ m_enumerator.Start(domain);
+ }
+ #endregion
+
+ #region Private Methods
+ ///
+ /// Finds the addresses for the specified host.
+ ///
+ private void OnFetchAddresses(object state)
+ {
+ ListViewItem listItem = state as ListViewItem;
+
+ if (listItem == null)
+ {
+ return;
+ }
+
+ string hostname = listItem.Tag as string;
+
+ if (hostname == null)
+ {
+ return;
+ }
+
+ try
+ {
+ IPAddress[] addresses = Dns.GetHostAddresses(hostname);
+
+ StringBuilder buffer = new StringBuilder();
+
+ for (int ii = 0; ii < addresses.Length; ii++)
+ {
+ if (buffer.Length > 0)
+ {
+ buffer.Append(", ");
+ }
+
+ buffer.AppendFormat("{0}", addresses[ii]);
+ }
+
+ ThreadPool.QueueUserWorkItem(new WaitCallback(OnUpdateAddress), new object[] { listItem, buffer.ToString() });
+ }
+ catch (Exception e)
+ {
+ Utils.Trace(e, "Could not get ip addresses for host: {0}", hostname);
+ ThreadPool.QueueUserWorkItem(new WaitCallback(OnUpdateAddress), new object[] { listItem, e.Message });
+ }
+ }
+
+ ///
+ /// Updates the addresses for a host.
+ ///
+ private void OnUpdateAddress(object state)
+ {
+ if (this.InvokeRequired)
+ {
+ this.BeginInvoke(new WaitCallback(OnUpdateAddress), state);
+ return;
+ }
+
+ ListViewItem listItem = ((object[])state)[0] as ListViewItem;
+
+ if (listItem == null)
+ {
+ return;
+ }
+
+ string addresses = ((object[])state)[1] as string;
+
+ if (addresses == null)
+ {
+ return;
+ }
+
+ listItem.SubItems[1].Text = addresses;
+
+ AdjustColumns();
+ }
+ #endregion
+
+ #region Overridden Methods
+ ///
+ /// Updates an item in the control.
+ ///
+ protected override void UpdateItem(ListViewItem listItem, object item)
+ {
+ string hostname = listItem.Tag as string;
+
+ if (hostname == null)
+ {
+ base.UpdateItem(listItem, hostname);
+ return;
+ }
+
+ listItem.SubItems[0].Text = String.Format("{0}", hostname);
+ listItem.SubItems[1].Text = "";
+
+ listItem.ImageKey = GuiUtils.Icons.Computer;
+
+ ThreadPool.QueueUserWorkItem(new WaitCallback(OnFetchAddresses), listItem);
+ }
+ #endregion
+
+ #region Event Handlers
+ private void HostEnumerator_HostsDiscovered(object sender, HostEnumeratorEventArgs e)
+ {
+ if (this.InvokeRequired)
+ {
+ this.BeginInvoke(new EventHandler(HostEnumerator_HostsDiscovered), sender, e);
+ return;
+ }
+
+ // check if this is the first callback.
+ if (m_waitingForHosts)
+ {
+ ItemsLV.Items.Clear();
+ m_waitingForHosts = false;
+ }
+
+ // populate list with hostnames.
+ if (e != null && e.Hostnames != null)
+ {
+ foreach (string hostname in e.Hostnames)
+ {
+ AddItem(hostname);
+ }
+ }
+
+ AdjustColumns();
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.Designer.cs
new file mode 100644
index 00000000..7a6d3712
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.Designer.cs
@@ -0,0 +1,197 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class HostListDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.HostsCTRL = new Opc.Ua.Client.Controls.HostListCtrl();
+ this.TopPN = new System.Windows.Forms.Panel();
+ this.DomainNameCTRL = new Opc.Ua.Client.Controls.SelectHostCtrl();
+ this.DomainLB = new System.Windows.Forms.Label();
+ this.ButtonsPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.TopPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(2, 254);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(455, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ this.OkBTN.Click += new System.EventHandler(this.OkBTN_Click);
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(376, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.Controls.Add(this.HostsCTRL);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(2, 23);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Padding = new System.Windows.Forms.Padding(0, 3, 0, 0);
+ this.MainPN.Size = new System.Drawing.Size(455, 231);
+ this.MainPN.TabIndex = 2;
+ //
+ // HostsCTRL
+ //
+ this.HostsCTRL.Cursor = System.Windows.Forms.Cursors.Default;
+ this.HostsCTRL.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.HostsCTRL.Instructions = null;
+ this.HostsCTRL.Location = new System.Drawing.Point(0, 3);
+ this.HostsCTRL.Name = "HostsCTRL";
+ this.HostsCTRL.Size = new System.Drawing.Size(455, 228);
+ this.HostsCTRL.TabIndex = 0;
+ this.HostsCTRL.ItemsPicked += new Opc.Ua.Client.Controls.ListItemActionEventHandler(this.HostsCTRL_ItemsPicked);
+ this.HostsCTRL.ItemsSelected += new Opc.Ua.Client.Controls.ListItemActionEventHandler(this.HostsCTRL_ItemsSelected);
+ //
+ // TopPN
+ //
+ this.TopPN.Controls.Add(this.DomainNameCTRL);
+ this.TopPN.Controls.Add(this.DomainLB);
+ this.TopPN.Dock = System.Windows.Forms.DockStyle.Top;
+ this.TopPN.Location = new System.Drawing.Point(2, 2);
+ this.TopPN.Name = "TopPN";
+ this.TopPN.Size = new System.Drawing.Size(455, 21);
+ this.TopPN.TabIndex = 1;
+ //
+ // DomainNameCTRL
+ //
+ this.DomainNameCTRL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.DomainNameCTRL.CommandText = "Refresh";
+ this.DomainNameCTRL.Location = new System.Drawing.Point(47, 0);
+ this.DomainNameCTRL.Margin = new System.Windows.Forms.Padding(0);
+ this.DomainNameCTRL.MaximumSize = new System.Drawing.Size(4096, 21);
+ this.DomainNameCTRL.MinimumSize = new System.Drawing.Size(400, 21);
+ this.DomainNameCTRL.Name = "DomainNameCTRL";
+ this.DomainNameCTRL.Padding = new System.Windows.Forms.Padding(2, 0, 0, 0);
+ this.DomainNameCTRL.SelectDomains = true;
+ this.DomainNameCTRL.Size = new System.Drawing.Size(408, 21);
+ this.DomainNameCTRL.TabIndex = 1;
+ this.DomainNameCTRL.HostConnected += new System.EventHandler(this.DomainNameCTRL_HostConnected);
+ this.DomainNameCTRL.HostSelected += new System.EventHandler(this.DomainNameCTRL_HostSelected);
+ //
+ // DomainLB
+ //
+ this.DomainLB.AutoSize = true;
+ this.DomainLB.Location = new System.Drawing.Point(0, 4);
+ this.DomainLB.Name = "DomainLB";
+ this.DomainLB.Size = new System.Drawing.Size(43, 13);
+ this.DomainLB.TabIndex = 0;
+ this.DomainLB.Text = "Domain";
+ this.DomainLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // HostListDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(459, 285);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.TopPN);
+ this.Controls.Add(this.ButtonsPN);
+ this.MaximumSize = new System.Drawing.Size(1024, 1024);
+ this.MinimumSize = new System.Drawing.Size(467, 319);
+ this.Name = "HostListDlg";
+ this.Padding = new System.Windows.Forms.Padding(2, 2, 2, 0);
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Discover Hosts";
+ this.ButtonsPN.ResumeLayout(false);
+ this.MainPN.ResumeLayout(false);
+ this.TopPN.ResumeLayout(false);
+ this.TopPN.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private HostListCtrl HostsCTRL;
+ private SelectHostCtrl DomainNameCTRL;
+ private System.Windows.Forms.Panel TopPN;
+ private System.Windows.Forms.Label DomainLB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.cs
new file mode 100644
index 00000000..cecc6ab0
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.cs
@@ -0,0 +1,179 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+using Opc.Ua.Configuration;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Allows the user to browse a list of servers.
+ ///
+ public partial class HostListDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Initializes the dialog.
+ ///
+ public HostListDlg()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private string m_domain;
+ private string m_hostname;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public string ShowDialog(string domain)
+ {
+ if (String.IsNullOrEmpty(domain))
+ {
+ domain = ConfigUtils.GetComputerWorkgroupOrDomain();
+ }
+
+ m_domain = domain;
+
+ DomainNameCTRL.Initialize(m_domain, null);
+ HostsCTRL.Initialize(m_domain);
+ OkBTN.Enabled = false;
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return null;
+ }
+
+ return m_hostname;
+ }
+ #endregion
+
+ #region Event Handlers
+ private void OkBTN_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ DialogResult = DialogResult.OK;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void DomainNameCTRL_HostSelected(object sender, SelectHostCtrlEventArgs e)
+ {
+ try
+ {
+ if (m_domain != e.Hostname)
+ {
+ m_domain = e.Hostname;
+ HostsCTRL.Initialize(m_domain);
+ m_hostname = null;
+ OkBTN.Enabled = false;
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void DomainNameCTRL_HostConnected(object sender, SelectHostCtrlEventArgs e)
+ {
+ try
+ {
+ m_domain = e.Hostname;
+ HostsCTRL.Initialize(m_domain);
+ m_hostname = null;
+ OkBTN.Enabled = false;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void HostsCTRL_ItemsSelected(object sender, ListItemActionEventArgs e)
+ {
+ try
+ {
+ m_hostname = null;
+
+ foreach (string hostname in e.Items)
+ {
+ m_hostname = hostname;
+ break;
+ }
+
+ OkBTN.Enabled = !String.IsNullOrEmpty(m_hostname);
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void HostsCTRL_ItemsPicked(object sender, ListItemActionEventArgs e)
+ {
+ try
+ {
+ m_hostname = null;
+
+ foreach (string hostname in e.Items)
+ {
+ m_hostname = hostname;
+ break;
+ }
+
+ if (!String.IsNullOrEmpty(m_hostname))
+ {
+ DialogResult = DialogResult.OK;
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/HostListDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.Designer.cs
new file mode 100644
index 00000000..f24457a2
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.Designer.cs
@@ -0,0 +1,122 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class SelectHostCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.HostsCB = new System.Windows.Forms.ComboBox();
+ this.ConnectPN = new System.Windows.Forms.Panel();
+ this.ConnectBTN = new System.Windows.Forms.Button();
+ this.ConnectPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // HostsCB
+ //
+ this.HostsCB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.HostsCB.FormattingEnabled = true;
+ this.HostsCB.Location = new System.Drawing.Point(0, 0);
+ this.HostsCB.Name = "HostsCB";
+ this.HostsCB.Size = new System.Drawing.Size(578, 21);
+ this.HostsCB.TabIndex = 0;
+ this.HostsCB.SelectedIndexChanged += new System.EventHandler(this.HostsCB_SelectedIndexChanged);
+ //
+ // ConnectPN
+ //
+ this.ConnectPN.Controls.Add(this.ConnectBTN);
+ this.ConnectPN.Dock = System.Windows.Forms.DockStyle.Right;
+ this.ConnectPN.Location = new System.Drawing.Point(581, 0);
+ this.ConnectPN.Margin = new System.Windows.Forms.Padding(0);
+ this.ConnectPN.Name = "ConnectPN";
+ this.ConnectPN.Size = new System.Drawing.Size(74, 21);
+ this.ConnectPN.TabIndex = 1;
+ //
+ // ConnectBTN
+ //
+ this.ConnectBTN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ConnectBTN.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.ConnectBTN.Location = new System.Drawing.Point(0, 0);
+ this.ConnectBTN.Name = "ConnectBTN";
+ this.ConnectBTN.Size = new System.Drawing.Size(74, 21);
+ this.ConnectBTN.TabIndex = 0;
+ this.ConnectBTN.Text = "Connect";
+ this.ConnectBTN.UseVisualStyleBackColor = true;
+ this.ConnectBTN.Click += new System.EventHandler(this.ConnectBTN_Click);
+ //
+ // SelectHostCtrl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.ConnectPN);
+ this.Controls.Add(this.HostsCB);
+ this.Margin = new System.Windows.Forms.Padding(0);
+ this.MaximumSize = new System.Drawing.Size(4096, 21);
+ this.MinimumSize = new System.Drawing.Size(400, 21);
+ this.Name = "SelectHostCtrl";
+ this.Padding = new System.Windows.Forms.Padding(2, 0, 0, 0);
+ this.Size = new System.Drawing.Size(655, 21);
+ this.ConnectPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ComboBox HostsCB;
+ private System.Windows.Forms.Panel ConnectPN;
+ private System.Windows.Forms.Button ConnectBTN;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.cs
new file mode 100644
index 00000000..77c7d816
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.cs
@@ -0,0 +1,263 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+
+using Opc.Ua.Configuration;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Displays a drop down list of hosts.
+ ///
+ public partial class SelectHostCtrl : UserControl
+ {
+ #region Constructors
+ ///
+ /// Initializes the control.
+ ///
+ public SelectHostCtrl()
+ {
+ InitializeComponent();
+ }
+ #endregion
+
+ #region Private Fields
+ private int m_selectedIndex;
+ private bool m_selectDomains;
+ private event EventHandler m_HostSelected;
+ private event EventHandler m_HostConnected;
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Whether the control is used to select domains instead of hosts.
+ ///
+ [System.ComponentModel.DefaultValue(false)]
+ public bool SelectDomains
+ {
+ get { return m_selectDomains; }
+ set { m_selectDomains = value; }
+ }
+
+ ///
+ /// The text displayed on the connect button.
+ ///
+ [System.ComponentModel.DefaultValue("Connect")]
+ public string CommandText
+ {
+ get { return ConnectBTN.Text; }
+ set { ConnectBTN.Text = value; }
+ }
+
+ ///
+ /// Displays a set of hostnames in the control.
+ ///
+ public void Initialize(string defaultHost, IList hostnames)
+ {
+ HostsCB.Items.Clear();
+
+ // add option to browse for hosts.
+ HostsCB.Items.Add("");
+
+ // add any existing hosts.
+ if (hostnames != null)
+ {
+ foreach (string hostname in hostnames)
+ {
+ HostsCB.Items.Add(hostname);
+ }
+ }
+
+ // set a suitable default hostname.
+ if (String.IsNullOrEmpty(defaultHost))
+ {
+ if (!m_selectDomains)
+ {
+ defaultHost = System.Net.Dns.GetHostName();
+ }
+ else
+ {
+ defaultHost = ConfigUtils.GetComputerWorkgroupOrDomain();
+ }
+
+ if (hostnames != null && hostnames.Count > 0)
+ {
+ defaultHost = hostnames[0];
+ }
+ }
+
+ // set the current selection.
+ m_selectedIndex = HostsCB.FindString(defaultHost);
+
+ if (m_selectedIndex == -1)
+ {
+ m_selectedIndex = HostsCB.Items.Add(defaultHost);
+ }
+
+ HostsCB.SelectedIndex = m_selectedIndex;
+ }
+
+ ///
+ /// Raised when a host is selected in the control.
+ ///
+ public event EventHandler HostSelected
+ {
+ add { m_HostSelected += value; }
+ remove { m_HostSelected -= value; }
+ }
+
+ ///
+ /// Raised when the connect button is clicked.
+ ///
+ public event EventHandler HostConnected
+ {
+ add { m_HostConnected += value; }
+ remove { m_HostConnected -= value; }
+ }
+ #endregion
+
+ #region Event Handlers
+ private void HostsCB_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ try
+ {
+ if (HostsCB.SelectedIndex != 0)
+ {
+ if (m_HostSelected != null)
+ {
+ m_HostSelected(this, new SelectHostCtrlEventArgs((string)HostsCB.SelectedItem));
+ }
+
+ m_selectedIndex = HostsCB.SelectedIndex;
+ return;
+ }
+
+ if (!m_selectDomains)
+ {
+ // prompt user to select a host.
+ string hostname = new HostListDlg().ShowDialog(null);
+
+ if (hostname == null)
+ {
+ HostsCB.SelectedIndex = m_selectedIndex;
+ return;
+ }
+
+ // set the current selection.
+ m_selectedIndex = HostsCB.FindString(hostname);
+
+ if (m_selectedIndex == -1)
+ {
+ m_selectedIndex = HostsCB.Items.Add(hostname);
+ }
+ }
+
+ HostsCB.SelectedIndex = m_selectedIndex;
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+
+ private void ConnectBTN_Click(object sender, EventArgs e)
+ {
+ try
+ { int index = HostsCB.SelectedIndex;
+
+ if (index == 0)
+ {
+ return;
+ }
+
+ if (m_HostConnected != null)
+ {
+ if (index == -1)
+ {
+ if (!String.IsNullOrEmpty(HostsCB.Text))
+ {
+ m_HostConnected(this, new SelectHostCtrlEventArgs(HostsCB.Text));
+ }
+
+ // add host to list.
+ m_selectedIndex = HostsCB.FindString(HostsCB.Text);
+
+ if (m_selectedIndex == -1)
+ {
+ m_selectedIndex = HostsCB.Items.Add(HostsCB.Text);
+ }
+
+ return;
+ }
+
+ m_HostConnected(this, new SelectHostCtrlEventArgs((string)HostsCB.SelectedItem));
+ }
+ }
+ catch (Exception exception)
+ {
+ GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
+ }
+ }
+ #endregion
+ }
+
+ #region SelectHostCtrlEventArgs Class
+ ///
+ /// The event arguments passed when the SelectHostCtrlEventArgs raises events.
+ ///
+ public class SelectHostCtrlEventArgs : EventArgs
+ {
+ ///
+ /// Initilizes the object with the current hostname.
+ ///
+ public SelectHostCtrlEventArgs(string hostname)
+ {
+ m_hostname = hostname;
+ }
+
+ ///
+ /// The current hostname.
+ ///
+ public string Hostname
+ {
+ get { return m_hostname; }
+ }
+
+ private string m_hostname;
+ }
+ #endregion
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/SelectHostCtrl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.Designer.cs
new file mode 100644
index 00000000..1e521bcc
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.Designer.cs
@@ -0,0 +1,192 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class UsernameTokenDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ButtonsPN = new System.Windows.Forms.Panel();
+ this.OkBTN = new System.Windows.Forms.Button();
+ this.CancelBTN = new System.Windows.Forms.Button();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.UserNameCB = new System.Windows.Forms.ComboBox();
+ this.PasswordTB = new System.Windows.Forms.TextBox();
+ this.PasswordLB = new System.Windows.Forms.Label();
+ this.UserNameLB = new System.Windows.Forms.Label();
+ this.ButtonsPN.SuspendLayout();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ButtonsPN
+ //
+ this.ButtonsPN.Controls.Add(this.OkBTN);
+ this.ButtonsPN.Controls.Add(this.CancelBTN);
+ this.ButtonsPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.ButtonsPN.Location = new System.Drawing.Point(0, 55);
+ this.ButtonsPN.Name = "ButtonsPN";
+ this.ButtonsPN.Size = new System.Drawing.Size(313, 31);
+ this.ButtonsPN.TabIndex = 0;
+ //
+ // OkBTN
+ //
+ this.OkBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.OkBTN.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.OkBTN.Location = new System.Drawing.Point(4, 4);
+ this.OkBTN.Name = "OkBTN";
+ this.OkBTN.Size = new System.Drawing.Size(75, 23);
+ this.OkBTN.TabIndex = 1;
+ this.OkBTN.Text = "OK";
+ this.OkBTN.UseVisualStyleBackColor = true;
+ //
+ // CancelBTN
+ //
+ this.CancelBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CancelBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBTN.Location = new System.Drawing.Point(234, 4);
+ this.CancelBTN.Name = "CancelBTN";
+ this.CancelBTN.Size = new System.Drawing.Size(75, 23);
+ this.CancelBTN.TabIndex = 0;
+ this.CancelBTN.Text = "Cancel";
+ this.CancelBTN.UseVisualStyleBackColor = true;
+ //
+ // panel1
+ //
+ this.panel1.Controls.Add(this.UserNameCB);
+ this.panel1.Controls.Add(this.PasswordTB);
+ this.panel1.Controls.Add(this.PasswordLB);
+ this.panel1.Controls.Add(this.UserNameLB);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel1.Location = new System.Drawing.Point(0, 0);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(313, 55);
+ this.panel1.TabIndex = 1;
+ //
+ // UserNameCB
+ //
+ this.UserNameCB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.UserNameCB.FormattingEnabled = true;
+ this.UserNameCB.Location = new System.Drawing.Point(65, 7);
+ this.UserNameCB.Name = "UserNameCB";
+ this.UserNameCB.Size = new System.Drawing.Size(244, 21);
+ this.UserNameCB.TabIndex = 5;
+ //
+ // PasswordTB
+ //
+ this.PasswordTB.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.PasswordTB.Location = new System.Drawing.Point(65, 31);
+ this.PasswordTB.Name = "PasswordTB";
+ this.PasswordTB.PasswordChar = '*';
+ this.PasswordTB.Size = new System.Drawing.Size(244, 20);
+ this.PasswordTB.TabIndex = 7;
+ //
+ // PasswordLB
+ //
+ this.PasswordLB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.PasswordLB.AutoSize = true;
+ this.PasswordLB.Location = new System.Drawing.Point(6, 35);
+ this.PasswordLB.Name = "PasswordLB";
+ this.PasswordLB.Size = new System.Drawing.Size(53, 13);
+ this.PasswordLB.TabIndex = 6;
+ this.PasswordLB.Text = "Password";
+ this.PasswordLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // UserNameLB
+ //
+ this.UserNameLB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.UserNameLB.AutoSize = true;
+ this.UserNameLB.Location = new System.Drawing.Point(6, 11);
+ this.UserNameLB.Name = "UserNameLB";
+ this.UserNameLB.Size = new System.Drawing.Size(60, 13);
+ this.UserNameLB.TabIndex = 4;
+ this.UserNameLB.Text = "User Name";
+ this.UserNameLB.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // UsernameTokenDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(313, 86);
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.ButtonsPN);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.Name = "UsernameTokenDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Specify User Name and Password";
+ this.ButtonsPN.ResumeLayout(false);
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel ButtonsPN;
+ private System.Windows.Forms.Button OkBTN;
+ private System.Windows.Forms.Button CancelBTN;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Label PasswordLB;
+ private System.Windows.Forms.Label UserNameLB;
+ private System.Windows.Forms.TextBox PasswordTB;
+ private System.Windows.Forms.ComboBox UserNameCB;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs
new file mode 100644
index 00000000..f630083b
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.cs
@@ -0,0 +1,100 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using System.Threading;
+using System.Security.Cryptography.X509Certificates;
+
+using Opc.Ua.Client;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// Prompts the user to provide a user name and password.
+ ///
+ public partial class UsernameTokenDlg : Form
+ {
+ #region Constructors
+ ///
+ /// Constructs a new instance.
+ ///
+ public UsernameTokenDlg()
+ {
+ InitializeComponent();
+ this.Icon = ClientUtils.GetAppIcon();
+ }
+ #endregion
+
+ #region Private Fields
+ #endregion
+
+ #region Public Interface
+ ///
+ /// Displays the dialog.
+ ///
+ public bool ShowDialog(UserNameIdentityToken token)
+ {
+ if (token != null)
+ {
+ UserNameCB.Text = token.UserName;
+
+ if (token.Password != null && token.Password.Length > 0)
+ {
+ PasswordTB.Text = new UTF8Encoding().GetString(token.Password);
+ }
+ }
+
+ if (ShowDialog() != DialogResult.OK)
+ {
+ return false;
+ }
+
+ token.UserName = UserNameCB.Text;
+
+ if (!String.IsNullOrEmpty(PasswordTB.Text))
+ {
+ token.Password = new UTF8Encoding().GetBytes(PasswordTB.Text);
+ }
+ else
+ {
+ token.Password = null;
+ }
+
+ return true;
+ }
+ #endregion
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.resx
new file mode 100644
index 00000000..d58980a3
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Endpoints/UsernameTokenDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.cs
new file mode 100644
index 00000000..fb0e416d
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.cs
@@ -0,0 +1,222 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Opc.Ua.Client.Controls
+{
+ ///
+ /// A dialog that displays an exception trace in an HTML page.
+ ///
+ public partial class ExceptionDlg : Form
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ExceptionDlg()
+ {
+ InitializeComponent();
+ }
+
+ private Exception m_exception;
+
+ ///
+ /// Replaces all special characters in the message.
+ ///
+ private string ReplaceSpecialCharacters(string message)
+ {
+ message = message.Replace("&", "&");
+ message = message.Replace("<", "<");
+ message = message.Replace(">", ">");
+ message = message.Replace("\"", """);
+ message = message.Replace("'", "'");
+ message = message.Replace("\r\n", "
");
+
+ return message;
+ }
+
+ private void AddBlock(StringBuilder buffer, string text)
+ {
+ AddBlock(buffer, text, 0);
+ }
+
+ private void AddBlock(StringBuilder buffer, string text, int level)
+ {
+ if (!String.IsNullOrEmpty(text))
+ {
+ if (level > 0)
+ {
+ if (level == 1)
+ {
+ buffer.Append("| ");
+ buffer.Append(" ");
+ }
+ else
+ {
+ buffer.Append(" |
| ");
+ buffer.Append(" ");
+ }
+
+ buffer.Append(ReplaceSpecialCharacters(text));
+ buffer.Append(" ");
+ buffer.Append(" |
");
+ }
+ }
+
+ private void Add(StringBuilder buffer, Exception e, bool showStackTrace)
+ {
+ AddBlock(buffer, "EXCEPTION (" + e.GetType().Name + ")", 1);
+ AddBlock(buffer, e.Message);
+
+ ServiceResultException sre = e as ServiceResultException;
+
+ if (sre != null)
+ {
+ ServiceResult sr = new ServiceResult(sre);
+
+ while (sr != null)
+ {
+ AddBlock(buffer, "SERVICE RESULT (" + new StatusCode(sr.Code).ToString() + ")", 2);
+
+ string text = (sr.LocalizedText != null) ? sr.LocalizedText.Text : null;
+
+ if (text != e.Message)
+ {
+ AddBlock(buffer, text);
+ }
+
+ AddBlock(buffer, sr.SymbolicId);
+ AddBlock(buffer, sr.NamespaceUri);
+
+ if (showStackTrace)
+ {
+ if (!String.IsNullOrEmpty(sre.AdditionalInfo))
+ {
+ AddBlock(buffer, "ADDITIONAL INFO (" + new StatusCode(sr.Code).ToString() + ")", 3);
+ AddBlock(buffer, sre.AdditionalInfo);
+ }
+ }
+
+ sr = sr.InnerResult;
+ }
+ }
+
+ if (showStackTrace)
+ {
+ AddBlock(buffer, "STACK TRACE", 3);
+ AddBlock(buffer, e.StackTrace);
+ }
+ }
+
+ private void Show(bool showStackTrace)
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.Append("");
+ //buffer.Append(ExceptionBrowser.Parent.Width);
+ //buffer.Append("px'>");
+ buffer.Append("");
+
+ Exception e = m_exception;
+
+ while (e != null)
+ {
+ Add(buffer, e, showStackTrace);
+ e = e.InnerException;
+ }
+
+ buffer.Append("
");
+ buffer.Append("");
+
+ ExceptionBrowser.DocumentText = buffer.ToString();
+ }
+
+ ///
+ /// Displays the exception in a dialog.
+ ///
+ public static void Show(string caption, Exception e)
+ {
+ // check if running as a service.
+ if (!Environment.UserInteractive)
+ {
+ Utils.Trace(e, "Unexpected error in '{0}'.", caption);
+ return;
+ }
+
+ new ExceptionDlg().ShowDialog(caption, e);
+ }
+
+ ///
+ /// Display the exception in the dialog.
+ ///
+ public void ShowDialog(string caption, Exception e)
+ {
+ if (!String.IsNullOrEmpty(caption))
+ {
+ Text = caption;
+ }
+
+ m_exception = e;
+
+ #if _DEBUG
+ ShowStackTracesCK.Checked = true;
+ #else
+ ShowStackTracesCK.Checked = false;
+ #endif
+
+ Show(ShowStackTracesCK.Checked);
+ ShowDialog();
+ }
+
+ private void OkButton_Click(object sender, EventArgs e)
+ {
+ Close();
+ }
+
+ private void ShowStackTracesCK_CheckedChanged(object sender, EventArgs e)
+ {
+ Show(ShowStackTracesCK.Checked);
+ }
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.designer.cs
new file mode 100644
index 00000000..fd758c93
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.designer.cs
@@ -0,0 +1,151 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+namespace Opc.Ua.Client.Controls
+{
+ partial class ExceptionDlg
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.BottomPN = new System.Windows.Forms.Panel();
+ this.ShowStackTracesCK = new System.Windows.Forms.CheckBox();
+ this.CloseBTN = new System.Windows.Forms.Button();
+ this.MainPN = new System.Windows.Forms.Panel();
+ this.ExceptionBrowser = new System.Windows.Forms.WebBrowser();
+ this.BottomPN.SuspendLayout();
+ this.MainPN.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // BottomPN
+ //
+ this.BottomPN.Controls.Add(this.ShowStackTracesCK);
+ this.BottomPN.Controls.Add(this.CloseBTN);
+ this.BottomPN.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.BottomPN.Location = new System.Drawing.Point(0, 181);
+ this.BottomPN.Name = "BottomPN";
+ this.BottomPN.Size = new System.Drawing.Size(780, 29);
+ this.BottomPN.TabIndex = 1;
+ //
+ // ShowStackTracesCK
+ //
+ this.ShowStackTracesCK.AutoSize = true;
+ this.ShowStackTracesCK.Location = new System.Drawing.Point(3, 7);
+ this.ShowStackTracesCK.Name = "ShowStackTracesCK";
+ this.ShowStackTracesCK.Size = new System.Drawing.Size(138, 17);
+ this.ShowStackTracesCK.TabIndex = 1;
+ this.ShowStackTracesCK.Text = "Show Exception Details";
+ this.ShowStackTracesCK.UseVisualStyleBackColor = true;
+ this.ShowStackTracesCK.CheckedChanged += new System.EventHandler(this.ShowStackTracesCK_CheckedChanged);
+ //
+ // CloseBTN
+ //
+ this.CloseBTN.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
+ this.CloseBTN.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CloseBTN.Location = new System.Drawing.Point(353, 3);
+ this.CloseBTN.Name = "CloseBTN";
+ this.CloseBTN.Size = new System.Drawing.Size(75, 23);
+ this.CloseBTN.TabIndex = 0;
+ this.CloseBTN.Text = "Close";
+ this.CloseBTN.UseVisualStyleBackColor = true;
+ //
+ // MainPN
+ //
+ this.MainPN.AutoSize = true;
+ this.MainPN.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+ this.MainPN.Controls.Add(this.ExceptionBrowser);
+ this.MainPN.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.MainPN.Location = new System.Drawing.Point(0, 0);
+ this.MainPN.Name = "MainPN";
+ this.MainPN.Size = new System.Drawing.Size(780, 181);
+ this.MainPN.TabIndex = 1;
+ //
+ // ExceptionBrowser
+ //
+ this.ExceptionBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ExceptionBrowser.Location = new System.Drawing.Point(0, 0);
+ this.ExceptionBrowser.MinimumSize = new System.Drawing.Size(20, 20);
+ this.ExceptionBrowser.Name = "ExceptionBrowser";
+ this.ExceptionBrowser.ScriptErrorsSuppressed = true;
+ this.ExceptionBrowser.Size = new System.Drawing.Size(780, 181);
+ this.ExceptionBrowser.TabIndex = 1;
+ //
+ // ExceptionDlg
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoSize = true;
+ this.ClientSize = new System.Drawing.Size(780, 210);
+ this.Controls.Add(this.MainPN);
+ this.Controls.Add(this.BottomPN);
+ this.MaximumSize = new System.Drawing.Size(4096, 4096);
+ this.Name = "ExceptionDlg";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Exception";
+ this.BottomPN.ResumeLayout(false);
+ this.BottomPN.PerformLayout();
+ this.MainPN.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel BottomPN;
+ private System.Windows.Forms.Button CloseBTN;
+ private System.Windows.Forms.Panel MainPN;
+ private System.Windows.Forms.WebBrowser ExceptionBrowser;
+ private System.Windows.Forms.CheckBox ShowStackTracesCK;
+
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.resx
new file mode 100644
index 00000000..19dc0dd8
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/ExceptionDlg.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.cs
new file mode 100644
index 00000000..071d6e26
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Windows.Forms;
+
+namespace Opc.Ua.Client.Controls
+{
+ public partial class HeaderBranding : UserControl
+ {
+ #region Public Constructors
+
+ public HeaderBranding()
+ {
+ InitializeComponent();
+ }
+
+ #endregion Public Constructors
+
+ #region Private Methods
+
+ private void pictureBox2_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ System.Diagnostics.Process.Start("http://www.steamware.net");
+ }
+ catch
+ {
+ }
+ }
+
+ private void ServerHeaderBranding_Load(object sender, EventArgs e)
+ {
+ labelVersion.Text = this.Parent.Text;
+ }
+
+ #endregion Private Methods
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.designer.cs
new file mode 100644
index 00000000..c56e9aba
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.designer.cs
@@ -0,0 +1,116 @@
+namespace Opc.Ua.Client.Controls
+{
+ partial class HeaderBranding
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HeaderBranding));
+ this.pictureBox1 = new System.Windows.Forms.PictureBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
+ this.appName = new System.Windows.Forms.Label();
+ this.labelVersion = new System.Windows.Forms.Label();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
+ this.SuspendLayout();
+ //
+ // pictureBox1
+ //
+ this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
+ this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
+ this.pictureBox1.Location = new System.Drawing.Point(7, 3);
+ this.pictureBox1.Name = "pictureBox1";
+ this.pictureBox1.Size = new System.Drawing.Size(177, 70);
+ this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
+ this.pictureBox1.TabIndex = 0;
+ this.pictureBox1.TabStop = false;
+ this.toolTip1.SetToolTip(this.pictureBox1, "Visit www.opcfoundation.org");
+ this.pictureBox1.Click += new System.EventHandler(this.pictureBox2_Click);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.BackColor = System.Drawing.Color.White;
+ this.label1.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label1.Location = new System.Drawing.Point(296, 37);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(192, 15);
+ this.label1.TabIndex = 3;
+ this.label1.Text = "OPC UA Technology Based Client";
+ //
+ // appName
+ //
+ this.appName.BackColor = System.Drawing.Color.White;
+ this.appName.Font = new System.Drawing.Font("Arial", 20F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.appName.Location = new System.Drawing.Point(201, 7);
+ this.appName.Name = "appName";
+ this.appName.Size = new System.Drawing.Size(382, 27);
+ this.appName.TabIndex = 8;
+ this.appName.Text = "OPC-UA Client Browser";
+ this.appName.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+ //
+ // labelVersion
+ //
+ this.labelVersion.AutoSize = true;
+ this.labelVersion.BackColor = System.Drawing.Color.White;
+ this.labelVersion.Font = new System.Drawing.Font("Arial", 7F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.labelVersion.Location = new System.Drawing.Point(404, 60);
+ this.labelVersion.Name = "labelVersion";
+ this.labelVersion.Size = new System.Drawing.Size(166, 13);
+ this.labelVersion.TabIndex = 9;
+ this.labelVersion.Text = "OPC UA Technology Based Client";
+ //
+ // HeaderBranding
+ //
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+ this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+ this.BackColor = System.Drawing.Color.White;
+ this.Controls.Add(this.labelVersion);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.pictureBox1);
+ this.Controls.Add(this.appName);
+ this.MaximumSize = new System.Drawing.Size(0, 100);
+ this.MinimumSize = new System.Drawing.Size(500, 80);
+ this.Name = "HeaderBranding";
+ this.Padding = new System.Windows.Forms.Padding(3);
+ this.Size = new System.Drawing.Size(591, 80);
+ this.Load += new System.EventHandler(this.ServerHeaderBranding_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.PictureBox pictureBox1;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.ToolTip toolTip1;
+ private System.Windows.Forms.Label appName;
+ private System.Windows.Forms.Label labelVersion;
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.resx
new file mode 100644
index 00000000..04b7e643
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/HeaderBranding.resx
@@ -0,0 +1,545 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ 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
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Array.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Array.bmp
new file mode 100644
index 00000000..ebece464
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Array.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Attribute.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Attribute.bmp
new file mode 100644
index 00000000..45b00e3e
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Attribute.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ByteString.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ByteString.bmp
new file mode 100644
index 00000000..a54ab10b
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ByteString.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ClosedFolder.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ClosedFolder.bmp
new file mode 100644
index 00000000..9b1d6163
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ClosedFolder.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Constant.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Constant.bmp
new file mode 100644
index 00000000..0a1ae943
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Constant.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/InputArgument.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/InputArgument.bmp
new file mode 100644
index 00000000..4f4956b4
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/InputArgument.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Method.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Method.bmp
new file mode 100644
index 00000000..b283fd23
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Method.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Number.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Number.bmp
new file mode 100644
index 00000000..5e5f6e75
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Number.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Object.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Object.bmp
new file mode 100644
index 00000000..4b7bb331
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Object.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Object2.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Object2.bmp
new file mode 100644
index 00000000..ea3ba17e
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Object2.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ObjectType.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ObjectType.bmp
new file mode 100644
index 00000000..bef5b781
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/ObjectType.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/OpenFolder.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/OpenFolder.bmp
new file mode 100644
index 00000000..bfd30f4b
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/OpenFolder.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/OutputArgument.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/OutputArgument.bmp
new file mode 100644
index 00000000..a93357fb
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/OutputArgument.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Property.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Property.bmp
new file mode 100644
index 00000000..d6341545
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Property.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Reference.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Reference.bmp
new file mode 100644
index 00000000..719f0681
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Reference.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/String.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/String.bmp
new file mode 100644
index 00000000..7a996462
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/String.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Structure.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Structure.bmp
new file mode 100644
index 00000000..5078c40d
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Structure.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Value.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Value.bmp
new file mode 100644
index 00000000..9a920005
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Value.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Variable.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Variable.bmp
new file mode 100644
index 00000000..f299c073
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Variable.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Varible.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Varible.bmp
new file mode 100644
index 00000000..048c9423
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/Varible.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/View.bmp b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/View.bmp
new file mode 100644
index 00000000..d3dfe9f2
Binary files /dev/null and b/IOB-OPC-UA/Applications/ClientControls.Net4/Icons/View.bmp differ
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/MessageDlg.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/MessageDlg.cs
new file mode 100644
index 00000000..1b967b7e
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/MessageDlg.cs
@@ -0,0 +1,62 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System.Threading.Tasks;
+using Opc.Ua.Configuration;
+using System.Windows.Forms;
+
+namespace Opc.Ua.Client.Controls
+{
+ public class ApplicationMessageDlg : IApplicationMessageDlg
+ {
+ private string message = string.Empty;
+ private MessageBoxButtons buttons = MessageBoxButtons.OK;
+
+ public override void Message(string text, bool ask)
+ {
+ message = text;
+
+ if (ask)
+ {
+ buttons = MessageBoxButtons.YesNo;
+ }
+ else
+ {
+ buttons = MessageBoxButtons.OK;
+ }
+ }
+
+ public override async Task ShowAsync()
+ {
+ DialogResult result = MessageBox.Show(message, "OPC UA", buttons);
+ return await Task.FromResult((result == DialogResult.OK) || (result == DialogResult.Yes));
+ }
+ }
+}
+
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/AssemblyInfo.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..62ee0e3c
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Opc.Ua.ClientControls")]
+[assembly: AssemblyDescription("UA Client Controls Library")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("OPC Foundation")]
+[assembly: AssemblyProduct("OPC UA SDK")]
+[assembly: AssemblyCopyright(AssemblyVersionInfo.Copyright)]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9ef9957a-78fc-4102-9469-4c7b501d301b")]
+
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/AssemblyVersionInfo.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/AssemblyVersionInfo.cs
new file mode 100644
index 00000000..6492ea10
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/AssemblyVersionInfo.cs
@@ -0,0 +1,38 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Reciprocal Community License ("RCL") Version 1.00
+ *
+ * Unless explicitly acquired and licensed from Licensor under another
+ * license, the contents of this file are subject to the Reciprocal
+ * Community License ("RCL") Version 1.00, or subsequent versions
+ * as allowed by the RCL, and You may not copy or use this file in either
+ * source code or executable form, except in compliance with the terms and
+ * conditions of the RCL.
+ *
+ * All software distributed under the RCL is provided strictly on an
+ * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+ * AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the RCL for specific
+ * language governing rights and limitations under the RCL.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/RCL/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+///
+/// Defines string constants for SDK version information.
+///
+internal static class AssemblyVersionInfo
+{
+ ///
+ /// The current copy right notice.
+ ///
+ public const string Copyright = "Copyright © 2004-2020 OPC Foundation, Inc";
+
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/Resources.Designer.cs b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..567268b2
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Opc.Ua.Client.Controls.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Opc.Ua.Client.Controls.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/Resources.resx b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/Resources.resx
new file mode 100644
index 00000000..7080a7d1
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/Properties/Resources.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/UA Client Controls.csproj b/IOB-OPC-UA/Applications/ClientControls.Net4/UA Client Controls.csproj
new file mode 100644
index 00000000..68d5754a
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/UA Client Controls.csproj
@@ -0,0 +1,1052 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {A247D2EE-14FC-463D-A9BA-6CFF1EF22B7A}
+ Library
+ Properties
+ Opc.Ua.Client.Controls
+ Opc.Ua.ClientControls
+ false
+
+
+
+
+ 3.5
+
+
+ v4.6.2
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ AnyCPU
+
+
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ AnyCPU
+
+
+ false
+
+
+
+
+
+
+ 3.0
+
+
+
+
+
+
+
+ AttributeListCtrl.cs
+
+
+ UserControl
+
+
+ UserControl
+
+
+ BrowseListCtrl.cs
+
+
+ UserControl
+
+
+ BrowseTreeCtrl.cs
+
+
+ UserControl
+
+
+ NodeListCtrl.cs
+
+
+ Form
+
+
+ SelectNodesDlg.cs
+
+
+ UserControl
+
+
+ UserControl
+
+
+ ClientUtils.cs
+
+
+ UserControl
+
+
+ AttrributesListViewCtrl.cs
+
+
+ UserControl
+
+
+ BrowseNodeCtrl.cs
+
+
+ UserControl
+
+
+ BrowseTreeViewCtrl.cs
+
+
+ Form
+
+
+ CallRequestDlg.cs
+
+
+ UserControl
+
+
+ CallRequestListViewCtrl.cs
+
+
+ UserControl
+
+
+ ConnectServerCtrl.cs
+
+
+ Form
+
+
+ EditAnnotationDlg.cs
+
+
+ Form
+
+
+ EditComplexValue2Dlg.cs
+
+
+ UserControl
+
+
+ EditComplexValueCtrl.cs
+
+
+ Form
+
+
+ EditComplexValueDlg.cs
+
+
+ Form
+
+
+ EditMonitoredItemDlg.cs
+
+
+ Form
+
+
+ EditReadValueIdDlg.cs
+
+
+ Form
+
+
+ EditSubscriptionDlg.cs
+
+
+ UserControl
+
+
+ EditValueCtrl.cs
+
+
+ Form
+
+
+ EditWriteValueDlg.cs
+
+
+ UserControl
+
+
+ EventFilterListViewCtrl.cs
+
+
+ UserControl
+
+
+ EventListViewCtrl.cs
+
+
+ Form
+
+
+ GdsDiscoverServersDlg.cs
+
+
+ Form
+
+
+ HistoryDataDlg.cs
+
+
+ UserControl
+
+
+ HistoryDataListView.cs
+
+
+ UserControl
+
+
+ HistoryEventCtrl.cs
+
+
+
+ Form
+
+
+ ReadRequestDlg.cs
+
+
+ UserControl
+
+
+ ReadRequestListViewCtrl.cs
+
+
+ Form
+
+
+ SelectLocaleDlg.cs
+
+
+ UserControl
+
+
+ SelectNodeCtrl.cs
+
+
+ Form
+
+
+ SelectNodeDlg.cs
+
+
+ Form
+
+
+ SetFilterOperatorDlg.cs
+
+
+ Form
+
+
+ SetTypeDlg.cs
+
+
+ Form
+
+
+ SubscribeDataDlg.cs
+
+
+ UserControl
+
+
+ SubscribeDataListViewCtrl.cs
+
+
+ Form
+
+
+ SubscribeEventsDlg.cs
+
+
+ UserControl
+
+
+ TypeFieldsListViewCtrl.cs
+
+
+ Form
+
+
+ UserNamePasswordDlg.cs
+
+
+ Form
+
+
+ ViewEventDetailsDlg.cs
+
+
+ Form
+
+
+ WriteRequestDlg.cs
+
+
+ UserControl
+
+
+ WriteRequestListViewCtrl.cs
+
+
+ UserControl
+
+
+ DiscoveredServerOnNetworkListCtrl.cs
+
+
+ Form
+
+
+ DiscoveredServerOnNetworkListDlg.cs
+
+
+ UserControl
+
+
+ SelectHostCtrl.cs
+
+
+ UserControl
+
+
+ DiscoveredServerListCtrl.cs
+
+
+ Form
+
+
+ DiscoveredServerListDlg.cs
+
+
+ UserControl
+
+
+ HostListCtrl.cs
+
+
+ Form
+
+
+ HostListDlg.cs
+
+
+ Code
+
+
+ UserControl
+
+
+ GuiUtils.cs
+
+
+ Form
+
+
+ EditArrayDlg.cs
+
+
+ Form
+
+
+ DiscoverServerDlg.cs
+
+
+ UserControl
+
+
+ EditDataValueCtrl.cs
+
+
+ Form
+
+
+ EditDataValueDlg.cs
+
+
+ UserControl
+
+
+ EditValueCtrl.cs
+
+
+ UserControl
+
+
+ EventListView.cs
+
+
+ UserControl
+
+
+ ReferenceListCtrl.cs
+
+
+ Form
+
+
+ ViewNodeStateDlg.cs
+
+
+ UserControl
+
+
+ BaseListCtrl.cs
+
+
+ UserControl
+
+
+ BaseTreeCtrl.cs
+
+
+ Code
+
+
+ Form
+
+
+ ComplexValueEditDlg.cs
+
+
+ UserControl
+
+
+ DataListCtrl.cs
+
+
+ Form
+
+
+ DateTimeValueEditDlg.cs
+
+
+ UserControl
+
+
+ NodeIdCtrl.cs
+
+
+ Form
+
+
+ NodeIdValueEditDlg.cs
+
+
+ Form
+
+
+ NumericValueEditDlg.cs
+
+
+ UserControl
+
+
+ ReferenceTypeCtrl.cs
+
+
+ Form
+
+
+ SimpleValueEditDlg.cs
+
+
+ Form
+
+
+ StringValueEditDlg.cs
+
+
+ Form
+
+
+ CertificateDlg.cs
+
+
+ UserControl
+
+
+ CertificateListCtrl.cs
+
+
+ Form
+
+
+ CertificateListDlg.cs
+
+
+
+ UserControl
+
+
+ CertificatePropertiesListCtrl.cs
+
+
+ UserControl
+
+
+ CertificateStoreCtrl.cs
+
+
+ Form
+
+
+ CertificateStoreDlg.cs
+
+
+ UserControl
+
+
+ CertificateStoreTreeCtrl.cs
+
+
+ Form
+
+
+ CertificateStoreTreeDlg.cs
+
+
+ UserControl
+
+
+ SelectUrlsCtrl.cs
+
+
+ Form
+
+
+ SelectProfileDlg.cs
+
+
+ UserControl
+
+
+ SelectProfileCtrl.cs
+
+
+ UserControl
+
+
+ SelectCertificateStoreCtrl.cs
+
+
+ UserControl
+
+
+ SelectFileCtrl.cs
+
+
+ Form
+
+
+ ViewCertificateDlg.cs
+
+
+ Form
+
+
+ YesNoDlg.cs
+
+
+ Form
+
+
+ ConfiguredServerDlg.cs
+
+
+ UserControl
+
+
+ ConfiguredServerListCtrl.cs
+
+
+ Form
+
+
+ ConfiguredServerListDlg.cs
+
+
+ UserControl
+
+
+ EndpointSelectorCtrl.cs
+
+
+ Form
+
+
+ UsernameTokenDlg.cs
+
+
+ Form
+
+
+ ExceptionDlg.cs
+
+
+ UserControl
+
+
+ HeaderBranding.cs
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ BrowseTreeCtrl.cs
+ Designer
+
+
+ NodeListCtrl.cs
+ Designer
+
+
+ SelectNodesDlg.cs
+ Designer
+
+
+ ClientUtils.cs
+ Designer
+
+
+ AttrributesListViewCtrl.cs
+ Designer
+
+
+ BrowseNodeCtrl.cs
+ Designer
+
+
+ BrowseTreeViewCtrl.cs
+ Designer
+
+
+ CallRequestDlg.cs
+ Designer
+
+
+ CallRequestListViewCtrl.cs
+ Designer
+
+
+ ConnectServerCtrl.cs
+ Designer
+
+
+ EditAnnotationDlg.cs
+ Designer
+
+
+ EditComplexValue2Dlg.cs
+ Designer
+
+
+ EditComplexValueCtrl.cs
+ Designer
+
+
+ EditComplexValueDlg.cs
+ Designer
+
+
+ EditMonitoredItemDlg.cs
+ Designer
+
+
+ EditReadValueIdDlg.cs
+ Designer
+
+
+ EditSubscriptionDlg.cs
+ Designer
+
+
+ EditValueCtrl.cs
+ Designer
+
+
+ EditWriteValueDlg.cs
+ Designer
+
+
+ EventFilterListViewCtrl.cs
+ Designer
+
+
+ EventListViewCtrl.cs
+ Designer
+
+
+ GdsDiscoverServersDlg.cs
+ Designer
+
+
+ HistoryDataDlg.cs
+ Designer
+
+
+ HistoryDataListView.cs
+ Designer
+
+
+ HistoryEventCtrl.cs
+ Designer
+
+
+ ReadRequestDlg.cs
+ Designer
+
+
+ ReadRequestListViewCtrl.cs
+ Designer
+
+
+ SelectLocaleDlg.cs
+ Designer
+
+
+ SelectNodeCtrl.cs
+ Designer
+
+
+ SelectNodeDlg.cs
+ Designer
+
+
+ SetFilterOperatorDlg.cs
+ Designer
+
+
+ SetTypeDlg.cs
+ Designer
+
+
+ SubscribeDataDlg.cs
+ Designer
+
+
+ SubscribeDataListViewCtrl.cs
+ Designer
+
+
+ SubscribeEventsDlg.cs
+ Designer
+
+
+ TypeFieldsListViewCtrl.cs
+ Designer
+
+
+ UserNamePasswordDlg.cs
+ Designer
+
+
+ ViewEventDetailsDlg.cs
+ Designer
+
+
+ WriteRequestDlg.cs
+ Designer
+
+
+ WriteRequestListViewCtrl.cs
+ Designer
+
+
+ DiscoveredServerOnNetworkListCtrl.cs
+
+
+ DiscoveredServerOnNetworkListDlg.cs
+
+
+ SelectHostCtrl.cs
+ Designer
+
+
+ DiscoveredServerListCtrl.cs
+ Designer
+
+
+ DiscoveredServerListDlg.cs
+ Designer
+
+
+ HostListCtrl.cs
+ Designer
+
+
+ HostListDlg.cs
+ Designer
+
+
+ GuiUtils.cs
+ Designer
+
+
+ EditArrayDlg.cs
+ Designer
+
+
+ DiscoverServerDlg.cs
+ Designer
+
+
+ EditDataValueCtrl.cs
+ Designer
+
+
+ EditDataValueDlg.cs
+ Designer
+
+
+ EditValueCtrl.cs
+ Designer
+
+
+ EventListView.cs
+ Designer
+
+
+ ReferenceListCtrl.cs
+ Designer
+
+
+ ViewNodeStateDlg.cs
+ Designer
+
+
+ BaseListCtrl.cs
+ Designer
+
+
+ BaseTreeCtrl.cs
+ Designer
+
+
+ ComplexValueEditDlg.cs
+ Designer
+
+
+ DataListCtrl.cs
+ Designer
+
+
+ DateTimeValueEditDlg.cs
+ Designer
+
+
+ NodeIdCtrl.cs
+ Designer
+
+
+ NodeIdValueEditDlg.cs
+ Designer
+
+
+ NumericValueEditDlg.cs
+ Designer
+
+
+ ReferenceTypeCtrl.cs
+ Designer
+
+
+ SimpleValueEditDlg.cs
+
+
+ StringValueEditDlg.cs
+ Designer
+
+
+ CertificateDlg.cs
+ Designer
+
+
+ CertificateListCtrl.cs
+ Designer
+
+
+ CertificateListDlg.cs
+ Designer
+
+
+ CertificateStoreCtrl.cs
+ Designer
+
+
+ CertificateStoreDlg.cs
+ Designer
+
+
+ CertificateStoreTreeCtrl.cs
+ Designer
+
+
+ CertificateStoreTreeDlg.cs
+ Designer
+
+
+ SelectUrlsCtrl.cs
+ Designer
+
+
+ SelectProfileDlg.cs
+ Designer
+
+
+ SelectProfileCtrl.cs
+ Designer
+
+
+ SelectCertificateStoreCtrl.cs
+ Designer
+
+
+ SelectFileCtrl.cs
+ Designer
+
+
+ ViewCertificateDlg.cs
+ Designer
+
+
+ YesNoDlg.cs
+ Designer
+
+
+ ConfiguredServerDlg.cs
+ Designer
+
+
+ ConfiguredServerListCtrl.cs
+ Designer
+
+
+ ConfiguredServerListDlg.cs
+ Designer
+
+
+ EndpointSelectorCtrl.cs
+ Designer
+
+
+ UsernameTokenDlg.cs
+ Designer
+
+
+ ExceptionDlg.cs
+
+
+ HeaderBranding.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+
+
+ Designer
+
+
+
+
+ {4b72937f-5a57-4cea-b9fe-b4c45cf7b284}
+ Opc.Ua.Security.Certificates
+
+
+ {d918c0f6-39bd-4ed0-8323-e5a2eb9a85da}
+ Opc.Ua.Core
+
+
+ {fe9eeb39-0698-4a19-b770-e66836ce0002}
+ Opc.Ua.Client.ComplexTypes
+
+
+ {15100583-bfef-431b-a1ea-1e5a843a39b1}
+ Opc.Ua.Client
+
+
+ {a39614ca-8ebe-4408-a9d2-38c7e5ae2a1d}
+ Opc.Ua.Configuration
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ClientControls.Net4/app.config b/IOB-OPC-UA/Applications/ClientControls.Net4/app.config
new file mode 100644
index 00000000..c76c89bb
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ClientControls.Net4/app.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/ConsoleReferenceClient.Config.xml b/IOB-OPC-UA/Applications/ConsoleReferenceClient/ConsoleReferenceClient.Config.xml
new file mode 100644
index 00000000..ba6ee40f
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/ConsoleReferenceClient.Config.xml
@@ -0,0 +1,89 @@
+
+
+ Quickstart Console Reference Client
+ urn:localhost:Quickstarts:Console ReferenceClient
+ uri:opcfoundation.org:Quickstarts:Console ReferenceClient
+ Client_1
+
+
+
+
+
+ Directory
+ %CommonApplicationData%\OPC Foundation\pki\own
+ CN=Quickstart Console Reference Client, C=US, S=Arizona, O=OPC Foundation, DC=localhost
+
+
+
+
+ Directory
+ %CommonApplicationData%\OPC Foundation\pki\issuer
+
+
+
+
+ Directory
+ %CommonApplicationData%\OPC Foundation\pki\trusted
+
+
+
+
+ Directory
+ %CommonApplicationData%\OPC Foundation\pki\rejected
+
+
+
+ false
+
+
+
+
+
+
+ 600000
+ 1048576
+ 1048576
+ 65535
+ 4194304
+ 65535
+ 300000
+ 3600000
+
+
+
+ 60000
+
+ opc.tcp://{0}:4840
+ http://{0}:52601/UADiscovery
+ http://{0}/UADiscovery/Default.svc
+
+
+ 10000
+
+
+
+
+
+
+ %CommonApplicationData%\OPC Foundation\Logs\Quickstarts.ConsoleReferenceClient.log.txt
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/ConsoleReferenceClient.csproj b/IOB-OPC-UA/Applications/ConsoleReferenceClient/ConsoleReferenceClient.csproj
new file mode 100644
index 00000000..cc6f323d
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/ConsoleReferenceClient.csproj
@@ -0,0 +1,30 @@
+
+
+
+ $(AppTargetFrameWorks)
+ ConsoleReferenceClient
+ Exe
+ ConsoleReferenceClient
+ OPC Foundation
+ .NET Console Reference Client
+ Copyright © 2004-2020 OPC Foundation, Inc
+ Quickstarts.ConsoleReferenceClient
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/Output.cs b/IOB-OPC-UA/Applications/ConsoleReferenceClient/Output.cs
new file mode 100644
index 00000000..3bae0165
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/Output.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Quickstarts.ConsoleReferenceClient
+{
+ public interface IOutput
+ {
+ void WriteLine(object obj);
+ void WriteLine(string msg);
+ void WriteLine(string msg, params object[] parameters);
+ }
+
+ public class ConsoleOutput : IOutput
+ {
+ public void WriteLine(object obj) => Console.WriteLine(obj);
+ public void WriteLine(string msg) => Console.WriteLine(msg);
+ public void WriteLine(string msg, params object[] parameters) => Console.WriteLine(msg, parameters);
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs b/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs
new file mode 100644
index 00000000..27f9dd9c
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/Program.cs
@@ -0,0 +1,87 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Threading.Tasks;
+using Opc.Ua;
+using Opc.Ua.Configuration;
+
+namespace Quickstarts.ConsoleReferenceClient
+{
+ public static class Program
+ {
+ public static async Task Main(string[] args)
+ {
+ IOutput console = new ConsoleOutput();
+ console.WriteLine("OPC UA Console Reference Client");
+ try
+ {
+ // Define the UA Client application
+ ApplicationInstance application = new ApplicationInstance();
+ application.ApplicationName = "Quickstart Console Reference Client";
+ application.ApplicationType = ApplicationType.Client;
+
+ // load the application configuration.
+ await application.LoadApplicationConfiguration("ConsoleReferenceClient.Config.xml", silent: false);
+ // check the application certificate.
+ await application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0);
+
+ // create the UA Client object and connect to configured server.
+ UAClient uaClient = new UAClient(application.ApplicationConfiguration, console, ClientBase.ValidateResponse);
+ bool connected = await uaClient.ConnectAsync();
+ if (connected)
+ {
+ // Run tests for available methods.
+ uaClient.ReadNodes();
+ uaClient.WriteNodes();
+ uaClient.Browse();
+ uaClient.CallMethod();
+
+ uaClient.SubscribeToDataChanges();
+ // Wait for some DataChange notifications from MonitoredItems
+ await Task.Delay(20_000);
+
+ uaClient.Disconnect();
+ }
+ else
+ {
+ console.WriteLine("Could not connect to server!");
+ }
+
+ console.WriteLine("\nProgram ended.");
+ console.WriteLine("Press any key to finish...");
+ Console.ReadKey();
+ }
+ catch (Exception ex)
+ {
+ console.WriteLine(ex.Message);
+ }
+ }
+ }
+}
diff --git a/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs b/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs
new file mode 100644
index 00000000..13c4f32e
--- /dev/null
+++ b/IOB-OPC-UA/Applications/ConsoleReferenceClient/UAClient.cs
@@ -0,0 +1,502 @@
+/* ========================================================================
+ * Copyright (c) 2005-2020 The OPC Foundation, Inc. All rights reserved.
+ *
+ * OPC Foundation MIT License 1.00
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The complete license agreement can be found here:
+ * http://opcfoundation.org/License/MIT/1.00/
+ * ======================================================================*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Opc.Ua;
+using Opc.Ua.Client;
+
+namespace Quickstarts.ConsoleReferenceClient
+{
+ ///
+ /// OPC UA Client with examples of basic functionality.
+ ///
+ class UAClient
+ {
+ #region Constructors
+ ///
+ /// Initializes a new instance of the UAClient class.
+ ///
+ public UAClient(ApplicationConfiguration configuration, IOutput output, Action validateResponse)
+ {
+ m_validateResponse = validateResponse;
+ m_output = output;
+ m_configuration = configuration;
+ m_configuration.CertificateValidator.CertificateValidation += CertificateValidation;
+ }
+ #endregion
+
+ #region Public Properties
+ ///
+ /// Gets the client session.
+ ///
+ public Session Session => m_session;
+
+ ///
+ /// Gets or sets the server URL.
+ ///
+ public string ServerUrl { get; set; } = "opc.tcp://localhost:62541/Quickstarts/ReferenceServer";
+ #endregion
+
+ #region Public Methods
+ ///
+ /// Creates a session with the UA server
+ ///
+ public async Task ConnectAsync()
+ {
+ try
+ {
+ if (m_session != null && m_session.Connected == true)
+ {
+ m_output.WriteLine("Session already connected!");
+ }
+ else
+ {
+ m_output.WriteLine("Connecting...");
+
+ // Get the endpoint by connecting to server's discovery endpoint.
+ // Try to find the first endopint without security.
+ EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(ServerUrl, false);
+
+ EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
+ ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
+
+ // Create the session
+ Session session = await Session.Create(
+ m_configuration,
+ endpoint,
+ false,
+ false,
+ m_configuration.ApplicationName,
+ 30 * 60 * 1000,
+ new UserIdentity(),
+ null
+ );
+
+ // Assign the created session
+ if (session != null && session.Connected)
+ {
+ m_session = session;
+ }
+
+ // Session created successfully.
+ m_output.WriteLine($"New Session Created with SessionName = {m_session.SessionName}");
+ }
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ m_output.WriteLine($"Create Session Error : {ex.Message}");
+ return false;
+ }
+ }
+
+ ///
+ /// Disconnects the session.
+ ///
+ public void Disconnect()
+ {
+ try
+ {
+ if (m_session != null)
+ {
+ m_output.WriteLine("Disconnecting...");
+
+ m_session.Close();
+ m_session.Dispose();
+ m_session = null;
+
+ // Log Session Disconnected event
+ m_output.WriteLine("Session Disconnected.");
+ }
+ else
+ {
+ m_output.WriteLine("Session not created!");
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ m_output.WriteLine($"Disconnect Error : {ex.Message}");
+ }
+ }
+
+ ///
+ /// Read a list of nodes from Server
+ ///
+ public void ReadNodes()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ m_output.WriteLine("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ #region Read a node by calling the Read Service
+
+ // build a list of nodes to be read
+ ReadValueIdCollection nodesToRead = new ReadValueIdCollection()
+ {
+ // Value of ServerStatus
+ new ReadValueId() { NodeId = Variables.Server_ServerStatus, AttributeId = Attributes.Value },
+ // BrowseName of ServerStatus_StartTime
+ new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.BrowseName },
+ // Value of ServerStatus_StartTime
+ new ReadValueId() { NodeId = Variables.Server_ServerStatus_StartTime, AttributeId = Attributes.Value }
+ };
+
+ // Read the node attributes
+ m_output.WriteLine("Reading nodes...");
+
+ // Call Read Service
+ m_session.Read(
+ null,
+ 0,
+ TimestampsToReturn.Both,
+ nodesToRead,
+ out DataValueCollection resultsValues,
+ out DiagnosticInfoCollection diagnosticInfos);
+
+ // Validate the results
+ m_validateResponse(resultsValues, nodesToRead);
+
+ // Display the results.
+ foreach (DataValue result in resultsValues)
+ {
+ m_output.WriteLine("Read Value = {0} , StatusCode = {1}", result.Value, result.StatusCode);
+ }
+ #endregion
+
+ #region Read the Value attribute of a node by calling the Session.ReadValue method
+ // Read Server NamespaceArray
+ m_output.WriteLine("Reading Value of NamespaceArray node...");
+ DataValue namespaceArray = m_session.ReadValue(Variables.Server_NamespaceArray);
+ // Display the result
+ m_output.WriteLine($"NamespaceArray Value = {namespaceArray}");
+ #endregion
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ m_output.WriteLine($"Read Nodes Error : {ex.Message}.");
+ }
+ }
+
+ ///
+ /// Write a list of nodes to the Server
+ ///
+ public void WriteNodes()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ m_output.WriteLine("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Write the configured nodes
+ WriteValueCollection nodesToWrite = new WriteValueCollection();
+
+ // Int32 Node - Objects\CTT\Scalar\Scalar_Static\Int32
+ WriteValue intWriteVal = new WriteValue();
+ intWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Int32");
+ intWriteVal.AttributeId = Attributes.Value;
+ intWriteVal.Value = new DataValue();
+ intWriteVal.Value.Value = (int)100;
+ nodesToWrite.Add(intWriteVal);
+
+ // Float Node - Objects\CTT\Scalar\Scalar_Static\Float
+ WriteValue floatWriteVal = new WriteValue();
+ floatWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_Float");
+ floatWriteVal.AttributeId = Attributes.Value;
+ floatWriteVal.Value = new DataValue();
+ floatWriteVal.Value.Value = (float)100.5;
+ nodesToWrite.Add(floatWriteVal);
+
+ // String Node - Objects\CTT\Scalar\Scalar_Static\String
+ WriteValue stringWriteVal = new WriteValue();
+ stringWriteVal.NodeId = new NodeId("ns=2;s=Scalar_Static_String");
+ stringWriteVal.AttributeId = Attributes.Value;
+ stringWriteVal.Value = new DataValue();
+ stringWriteVal.Value.Value = "String Test";
+ nodesToWrite.Add(stringWriteVal);
+
+ // Write the node attributes
+ StatusCodeCollection results = null;
+ DiagnosticInfoCollection diagnosticInfos;
+ m_output.WriteLine("Writing nodes...");
+
+ // Call Write Service
+ m_session.Write(null,
+ nodesToWrite,
+ out results,
+ out diagnosticInfos);
+
+ // Validate the response
+ m_validateResponse(results, nodesToWrite);
+
+ // Display the results.
+ m_output.WriteLine("Write Results :");
+
+ foreach (StatusCode writeResult in results)
+ {
+ m_output.WriteLine(" {0}", writeResult);
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ m_output.WriteLine($"Write Nodes Error : {ex.Message}.");
+ }
+ }
+
+ ///
+ /// Browse Server nodes
+ ///
+ public void Browse()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ m_output.WriteLine("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Create a Browser object
+ Browser browser = new Browser(m_session);
+
+ // Set browse parameters
+ browser.BrowseDirection = BrowseDirection.Forward;
+ browser.NodeClassMask = (int)NodeClass.Object | (int)NodeClass.Variable;
+ browser.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
+
+ NodeId nodeToBrowse = ObjectIds.Server;
+
+ // Call Browse service
+ m_output.WriteLine("Browsing {0} node...", nodeToBrowse);
+ ReferenceDescriptionCollection browseResults = browser.Browse(nodeToBrowse);
+
+ // Display the results
+ m_output.WriteLine("Browse returned {0} results:", browseResults.Count);
+
+ foreach (ReferenceDescription result in browseResults)
+ {
+ m_output.WriteLine(" DisplayName = {0}, NodeClass = {1}", result.DisplayName.Text, result.NodeClass);
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log Error
+ m_output.WriteLine($"Browse Error : {ex.Message}.");
+ }
+ }
+
+ ///
+ /// Call UA method
+ ///
+ public void CallMethod()
+ {
+ if (m_session == null || m_session.Connected == false)
+ {
+ m_output.WriteLine("Session not connected!");
+ return;
+ }
+
+ try
+ {
+ // Define the UA Method to call
+ // Parent node - Objects\CTT\Methods
+ // Method node - Objects\CTT\Methods\Add
+ NodeId objectId = new NodeId("ns=2;s=Methods");
+ NodeId methodId = new NodeId("ns=2;s=Methods_Add");
+
+ // Define the method parameters
+ // Input argument requires a Float and an UInt32 value
+ object[] inputArguments = new object[] { (float)10.5, (uint)10 };
+ IList