Files
Mapo-IOB-WIN/IOB-OPC-UA/Applications/ClientControls.Net4/Browse/BrowseTreeCtrl.cs
T
2021-03-25 18:25:25 +01:00

489 lines
16 KiB
C#

/* ========================================================================
* 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;
namespace Opc.Ua.Client.Controls
{
/// <summary>
/// Displays a hierarchy of nodes.
/// </summary>
public partial class BrowseTreeCtrl : Opc.Ua.Client.Controls.BaseTreeCtrl
{
/// <summary>
/// Initializes a new instance of the <see cref="BrowseTreeCtrl"/> class.
/// </summary>
public BrowseTreeCtrl()
{
InitializeComponent();
foreach (BrowseDirection value in Enum.GetValues(typeof(BrowseDirection)))
{
BrowseDirectionCTRL.Items.Add(value);
}
}
private NodeId m_rootId;
private NodeId m_viewId;
private Session m_session;
private NodeId m_referenceTypeId;
private BrowseDirection m_browseDirection;
private BrowseListCtrl m_referencesCTRL;
private AttributeListCtrl m_attributesCTRL;
private event EventHandler<NodesSelectedEventArgs> m_nodesSelected;
/// <summary>
/// The control that displays the non-hierarchial references for the selected node.
/// </summary>
public BrowseListCtrl ReferencesCTRL
{
get { return m_referencesCTRL; }
set { m_referencesCTRL = value; }
}
/// <summary>
/// The control that displays the attributes/properties for the selected node.
/// </summary>
public AttributeListCtrl AttributesCTRL
{
get { return m_attributesCTRL; }
set { m_attributesCTRL = value; }
}
/// <summary>
/// Raised when the select menu item is clicked.
/// </summary>
public event EventHandler<NodesSelectedEventArgs> NodesSelected
{
add { m_nodesSelected += value; }
remove { m_nodesSelected -= value; }
}
#region NodesSelectedEventArgs Class
/// <summary>
/// Specifies the nodes that where selected in the control.
/// </summary>
public class NodesSelectedEventArgs : EventArgs
{
/// <summary>
/// Constructs a new object.
/// </summary>
public NodesSelectedEventArgs(IList<ReferenceDescription> nodes)
{
m_nodes = nodes;
}
/// <summary>
/// The nodes that where selected.
/// </summary>
public IList<ReferenceDescription> Nodes
{
get { return m_nodes; }
}
private IList<ReferenceDescription> m_nodes;
}
#endregion
/// <summary>
/// Displays the a root in the control.
/// </summary>
public void Initialize(
Session session,
NodeId rootId,
NodeId viewId,
NodeId referenceTypeId,
BrowseDirection browseDirection)
{
m_session = session;
m_rootId = rootId;
m_viewId = viewId;
m_referenceTypeId = referenceTypeId;
m_browseDirection = browseDirection;
NodesTV.Nodes.Clear();
if (m_session == null)
{
return;
}
if (NodeId.IsNull(m_rootId))
{
m_rootId = Objects.RootFolder;
}
if (NodeId.IsNull(m_referenceTypeId))
{
m_referenceTypeId = ReferenceTypeIds.HierarchicalReferences;
}
ReferenceTypeCTRL.Initialize(m_session, ReferenceTypeIds.HierarchicalReferences);
ReferenceTypeCTRL.SelectedTypeId = m_referenceTypeId;
ILocalNode root = m_session.NodeCache.Find(m_rootId) as ILocalNode;
if (root == null)
{
return;
}
ReferenceDescription reference = new ReferenceDescription();
reference.ReferenceTypeId = referenceTypeId;
reference.IsForward = true;
reference.NodeId = root.NodeId;
reference.NodeClass = root.NodeClass;
reference.BrowseName = root.BrowseName;
reference.DisplayName = root.DisplayName;
reference.TypeDefinition = root.TypeDefinitionId;
TreeNode rootNode = new TreeNode(reference.ToString());
rootNode.ImageKey = rootNode.SelectedImageKey = GuiUtils.GetTargetIcon(session, reference);
rootNode.Tag = reference;
rootNode.Nodes.Add(new TreeNode());
NodesTV.Nodes.Add(rootNode);
}
/// <summary>
/// Browses the children of the node and updates the tree.
/// </summary>
private bool BrowseChildren(TreeNode parent)
{
ReferenceDescription reference = parent.Tag as ReferenceDescription;
if (reference == null)
{
return false;
}
parent.Nodes.Clear();
if (reference.NodeId.IsAbsolute)
{
return false;
}
BrowseDescription nodeToBrowse = new BrowseDescription();
nodeToBrowse.NodeId = (NodeId)reference.NodeId;
nodeToBrowse.BrowseDirection = m_browseDirection;
nodeToBrowse.ReferenceTypeId = m_referenceTypeId;
nodeToBrowse.IncludeSubtypes = true;
nodeToBrowse.NodeClassMask = 0;
nodeToBrowse.ResultMask = (uint)(int)BrowseResultMask.All;
BrowseDescriptionCollection nodesToBrowse = new BrowseDescriptionCollection();
nodesToBrowse.Add(nodeToBrowse);
ViewDescription view = null;
if (NodeId.IsNull(m_viewId))
{
view = new ViewDescription();
view.ViewId = m_viewId;
view.Timestamp = DateTime.MinValue;
view.ViewVersion = 0;
}
BrowseResultCollection results = null;
DiagnosticInfoCollection diagnosticInfos = null;
m_session.Browse(
null,
view,
0,
nodesToBrowse,
out results,
out diagnosticInfos);
if (results.Count != 1 || StatusCode.IsBad(results[0].StatusCode))
{
return false;
}
UpdateNode(parent, results[0].References);
while (results[0].ContinuationPoint != null && results[0].ContinuationPoint.Length > 0)
{
ByteStringCollection continuationPoints = new ByteStringCollection();
continuationPoints.Add(results[0].ContinuationPoint);
m_session.BrowseNext(
null,
parent == null,
continuationPoints,
out results,
out diagnosticInfos);
if (results.Count != 1 || StatusCode.IsBad(results[0].StatusCode))
{
return false;
}
UpdateNode(parent, results[0].References);
}
return true;
}
/// <summary>
/// Adds the browse results to the node (if not null).
/// </summary>
private void UpdateNode(TreeNode parent, ReferenceDescriptionCollection references)
{
try
{
for (int ii = 0; ii < references.Count; ii++)
{
ReferenceDescription reference = references[ii];
TreeNode childNode = new TreeNode(reference.ToString());
childNode.ImageKey = childNode.SelectedImageKey = GuiUtils.GetTargetIcon(m_session, reference);
childNode.Tag = reference;
childNode.Nodes.Add(new TreeNode());
parent.Nodes.Add(childNode);
}
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
}
}
#region Overridden Members
/// <see cref="BaseTreeCtrl.SelectNode" />
protected override void SelectNode()
{
base.SelectNode();
ReferenceDescription reference = NodesTV.SelectedNode.Tag as ReferenceDescription;
if (reference == null)
{
return;
}
// update attributes control.
if (AttributesCTRL != null)
{
AttributesCTRL.Initialize(m_session, reference.NodeId);
}
// update references control.
if (ReferencesCTRL != null)
{
ReferencesCTRL.Initialize(m_session, reference.NodeId);
}
}
/// <see cref="BaseTreeCtrl.BeforeExpand" />
protected override bool BeforeExpand(TreeNode clickedNode)
{
try
{
// check if a placeholder child is present.
if (clickedNode.Nodes.Count == 1 && clickedNode.Nodes[0].Text == String.Empty)
{
// browse.
return !BrowseChildren(clickedNode);
}
// do not cancel expand.
return false;
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
return false;
}
}
/// <see cref="BaseTreeCtrl.EnableMenuItems" />
protected override void EnableMenuItems(TreeNode clickedNode)
{
if (NodesTV.SelectedNode == null)
{
return;
}
SelectMI.Enabled = true;
if (NodesTV.SelectedNode.Nodes.Count > 0 && NodesTV.SelectedNode.Nodes[0].Text != String.Empty)
{
SelectChildrenMI.Enabled = true;
}
}
#endregion
#region Event Handlers
private void RootBTN_Click(object sender, EventArgs e)
{
try
{
if (NodesTV.SelectedNode == null)
{
return;
}
ReferenceDescription reference = NodesTV.SelectedNode.Tag as ReferenceDescription;
if (reference == null || reference.NodeId.IsAbsolute)
{
return;
}
Initialize(m_session, (NodeId)reference.NodeId, m_viewId, m_referenceTypeId, m_browseDirection);
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
}
}
private void BrowseDirectionCTRL_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
m_browseDirection = (BrowseDirection)BrowseDirectionCTRL.SelectedItem;
if (NodesTV.SelectedNode != null)
{
NodesTV.SelectedNode.Collapse();
NodesTV.SelectedNode.Nodes.Clear();
NodesTV.SelectedNode.Nodes.Add(new TreeNode());
NodesTV.SelectedNode.Expand();
return;
}
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
}
}
private void SelectMI_Click(object sender, EventArgs e)
{
try
{
if (m_nodesSelected != null)
{
if (NodesTV.SelectedNode == null)
{
return;
}
ReferenceDescription reference = NodesTV.SelectedNode.Tag as ReferenceDescription;
if (reference != null)
{
ReferenceDescriptionCollection collection = new ReferenceDescriptionCollection();
collection.Add(reference);
m_nodesSelected(this, new NodesSelectedEventArgs(collection));
}
}
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
}
}
private void SelectChildrenMI_Click(object sender, EventArgs e)
{
try
{
if (m_nodesSelected != null)
{
if (NodesTV.SelectedNode == null || NodesTV.SelectedNode.Nodes.Count == 0)
{
return;
}
ReferenceDescriptionCollection collection = new ReferenceDescriptionCollection();
foreach (TreeNode child in NodesTV.SelectedNode.Nodes)
{
ReferenceDescription reference = child.Tag as ReferenceDescription;
if (reference != null)
{
collection.Add(reference);
}
}
if (collection.Count > 0)
{
m_nodesSelected(this, new NodesSelectedEventArgs(collection));
}
}
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
}
}
private void ReferenceTypeCTRL_ReferenceSelectionChanged(object sender, ReferenceTypeCtrl.ReferenceSelectedEventArgs e)
{
try
{
m_referenceTypeId = e.ReferenceTypeId;
if (NodesTV.SelectedNode != null)
{
NodesTV.SelectedNode.Collapse();
NodesTV.SelectedNode.Nodes.Clear();
NodesTV.SelectedNode.Nodes.Add(new TreeNode());
NodesTV.SelectedNode.Expand();
return;
}
}
catch (Exception exception)
{
GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception);
}
}
#endregion
}
}