File LabelControl.xaml.cs¶
File List > PGRControls > LabelControl.xaml.cs
Go to the documentation of this file
//=============================================================================
// Copyright (c) 2026 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
//
// This software is the confidential and proprietary information of FLIR
// Integrated Imaging Solutions, Inc. ("Confidential Information"). You
// shall not disclose such Confidential Information and shall use it only in
// accordance with the terms of the license agreement you entered into
// with FLIR Integrated Imaging Solutions, Inc. (FLIR).
//
// FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
// SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
// SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
// THIS SOFTWARE OR ITS DERIVATIVES.
//=============================================================================
using System;
using SpinnakerNET.GenApi;
using System.Windows;
using System.Windows.Threading;
using System.ComponentModel;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Threading;
namespace SpinnakerNET.GUI
{
namespace WPFControls
{
public sealed partial class LabelControl : BaseClass
{
#region FIELDS
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(LabelControl));
private bool _disposed = false;
private IValue _node;
private string _unit = "";
private IFloat _floatNode;
private IInteger _integerNode;
private IEnum _enumNode;
private IString _stringNode;
private string _contentLabel;
public delegate void ControlUpdated(INode node);
public event ControlUpdated OnControlUpdated;
// GenICam callback update thread
BackgroundWorker _updateWorker;
DateTime lastPollTime;
private bool _forceUpdateEvenIfNotVisible = false;
#endregion
#region PROPERTIES
public string ContentLabel
{
get
{
return _contentLabel;
}
set
{
_contentLabel = value;
NotifyPropertyChanged("ContentLabel");
}
}
public System.Windows.Visibility ContentVisibility
{
get
{
return this.content.Visibility;
}
set
{
this.content.Visibility = value;
}
}
public bool ForceUpdateEvenIfNotVisible
{
get
{
return _forceUpdateEvenIfNotVisible;
}
set
{
_forceUpdateEvenIfNotVisible = value;
}
}
#endregion
#region Constructor
public LabelControl()
{
InitializeComponent();
_timer = new System.Windows.Forms.Timer();
ContentLabel = "";
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
lastPollTime = DateTime.Now;
}
internal LabelControl(LabelControl originalControl)
{
InitializeComponent();
_timer = new System.Windows.Forms.Timer();
ContentLabel = "";
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
// Common Properties
this.SetMapper(originalControl.GetMapper());
this.Connect(
originalControl.NodeMap, originalControl.GetNodeToControl(), originalControl.GetControlNameLabel());
this.SetNameLabelBoldness(originalControl.NameLabelBoldness);
this.SetVisibility(originalControl.GetVisibility());
this.SetControlID(originalControl.GetControlID());
this.SetMin(originalControl.GetMin());
this.SetMax(originalControl.GetMax());
this.SetControlNameLabel(originalControl.ControlNameLabel);
this.SetNameLabelVisibility(originalControl.NameLabelVisibility);
this.SetNameLabelBoldness(originalControl.GetNameLabelBoldness());
try
{
this.SetToolTip(originalControl.GetToolTip());
}
catch (System.Exception /*ex*/)
{
}
this.SetMaximumControlSize(originalControl.GetMaximumControlSize());
this.SetMinimumControlSize(originalControl.GetMinimumControlSize());
this.SetControlHeight(originalControl.GetControlHeight());
this.SetControlWidth(originalControl.GetControlWidth());
this.SetRefreshTime(originalControl.GetRefreshTime());
this.SetMargin(originalControl.GetMargin());
this.ContentVisibility = originalControl.ContentVisibility;
}
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
}
// Consider GenICam callbacks as unmanaged resource
Disconnect();
_disposed = true;
}
// Call Dispose in the base class.
base.Dispose(disposing);
}
#endregion
#region ICAMERACONTROL_IMPLEMENTATION
public override void SetRefreshTime(int seconds)
{
this._refreshTime = seconds;
// Start timer if an valid refresh time was provided
if (this._refreshTime > 0)
{
try
{
_timer = new System.Windows.Forms.Timer();
_timer.Interval = this._refreshTime;
_timer.Tick += new EventHandler(timer_Tick);
_timer.Start();
}
catch (System.Exception /*ex*/)
{
}
}
}
public override void Connect(INodeMap nodemap, string nodename, string namelabel = "")
{
if (nodemap != null && nodename != null && nodename.Length > 0)
{
// Acquire device serial number
if (string.IsNullOrWhiteSpace(_serialNumber))
{
_serialNumber = RetrieveSerialNumber(nodemap);
}
// Acquire device model name
if (string.IsNullOrWhiteSpace(_deviceModelName))
{
_deviceModelName = RetrieveModelName(nodemap);
}
try
{
// Get Name Label from GenICam Node
this._node = nodemap.GetNode<IValue>(nodename);
if (_node == null)
{
_featureAvailable = false;
throw new Exception($"Feature {nodename} not found");
}
this._nodeMap = nodemap;
this._propertyToControl = nodename;
}
catch (Exception ex)
{
log.Debug(string.Format("{0}Problem accessing {1}.", FormattedSerialNumber, nodename), ex);
}
if (_node != null)
{
try
{
_initializing = true;
this._nodeType = _node.GetType();
RegisterGeniCamCallback(nodemap, nodename, _node);
UpdateLabelDisplay(nodemap, nodename, _node);
SetToolTip(_node.ToolTip.ToString());
// RegisterInterfaceEvents();
_featureAvailable = _node.IsImplemented;
}
catch (System.Exception ex)
{
log.Debug(
string.Format(
"{1}Problem accessing {0} node.", this._propertyToControl, FormattedSerialNumber),
ex);
throw new Exception(string.Format("Problem accessing {0} node", this._propertyToControl));
}
finally
{
_initializing = false;
}
}
else
{
_featureAvailable = false;
}
}
else
{
// Standard label control with user specified text
this.ControlNameLabel = namelabel;
SetControlNameLabel(this._controlNameLabel);
this.content.Visibility = System.Windows.Visibility.Collapsed;
_featureAvailable = true;
}
}
public override void Disconnect()
{
try
{
UnregisterGeniCamCallback(NodeMap, PropertyToControl, _node);
_node = null;
_floatNode = null;
_integerNode = null;
_boolNode = null;
_mapper = null;
_nodeMap = null;
base.Disconnect();
}
catch (System.Exception /*ex*/)
{
}
}
private void UnregisterGeniCamCallback(INodeMap nodemap, string nodename, IValue node)
{
if (nodemap == null || node == null)
{
return;
}
Type type = node.GetType();
if (type == typeof (Float) && _floatNode != null && _callbackRegistered)
{
_floatNode.Updated -= LabelControlNode_Updated;
}
else if (type == typeof (Integer) && _integerNode != null && _callbackRegistered)
{
_integerNode.Updated -= LabelControlNode_Updated;
}
else if (type == typeof (BoolNode) && _boolNode != null && _callbackRegistered)
{
_boolNode.Updated -= LabelControlNode_Updated;
}
else if (type == typeof (Enumeration) && _enumNode != null && _callbackRegistered)
{
_enumNode.Updated -= LabelControlNode_Updated;
}
else if (type == typeof (StringNode) && _stringNode != null && _callbackRegistered)
{
_stringNode.Updated -= LabelControlNode_Updated;
}
else
{
}
}
private void RegisterGeniCamCallback(INodeMap nodemap, string nodename, IValue node)
{
Type type = node.GetType();
if (type == typeof (Float))
{
_floatNode = nodemap.GetNode<IFloat>(nodename);
_floatNode.Updated += LabelControlNode_Updated;
}
else if (type == typeof (Integer) || type == typeof (IntReg))
{
_integerNode = nodemap.GetNode<IInteger>(nodename);
_integerNode.Updated += LabelControlNode_Updated;
}
else if (type == typeof (BoolNode))
{
_boolNode = nodemap.GetNode<IBool>(nodename);
_boolNode.Updated += LabelControlNode_Updated;
}
else if (type == typeof (Enumeration))
{
_enumNode = nodemap.GetNode<Enumeration>(nodename);
_enumNode.Updated += LabelControlNode_Updated;
}
else if (type == typeof (StringNode))
{
_stringNode = nodemap.GetNode<StringNode>(nodename);
_stringNode.Updated += LabelControlNode_Updated;
}
else
{
}
_callbackRegistered = true;
}
internal override CameraControlCollection GetDependencyControls()
{
return null;
}
#endregion
#region EVENT_HANDLER
void timer_Tick(object sender, EventArgs e)
{
Refresh();
}
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
private void
_updateWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bool refreshRequired = false;
if (e.Cancelled)
{
return;
}
if (_nodeMap == null)
{
// Nodemap is no longer valid. Control must have been disconnected.
return;
}
// Go through each item to see if update is necessary
try
{
_isUpdating = true;
_initializing = true;
INode node = e.Result as INode;
NodeStatus currentNodeStatus = new NodeStatus(node, _mapper);
if (currentNodeStatus.ExceptionObject != null)
{
return;
}
string logMessage =
string.Format("Spinnaker Callback: Feature=\"{0}\"", currentNodeStatus.NodeName);
if (currentNodeStatus.IsReadable)
{
logMessage += string.Format(", Value=\"{0}\"", currentNodeStatus.CurrentValue);
}
LogNodeCallback(log, currentNodeStatus.NodeName, logMessage);
if (ControlNameLabel != currentNodeStatus.NodeDisplayName)
{
SetControlNameLabel(currentNodeStatus.NodeDisplayName);
}
if (this._unit != currentNodeStatus.Unit)
{
_unit = currentNodeStatus.Unit;
}
if (currentNodeStatus.IsReadable && ContentLabel != currentNodeStatus.CurrentStringValue)
{
UpdateLabelDisplay(_nodeMap, _propertyToControl, _node);
refreshRequired = true;
}
if (OnControlUpdated != null)
{
OnControlUpdated(currentNodeStatus.CurrentNode);
}
}
catch (System.Exception ex)
{
log.Debug(
string.Format(
"{1}Problem updating control for {0} node", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_initializing = false;
_isUpdating = false;
}
if (!refreshRequired)
{
return;
}
if (!Dispatcher.CheckAccess())
{
Dispatcher.BeginInvoke((Action)(() => { Refresh(); }), DispatcherPriority.Background, null);
}
else
{
Refresh();
}
}
private void _updateWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Limit the refresh rate
Thread.Sleep(1000 / _maxRefreshRateHz);
INode node = e.Argument as INode;
e.Result = node;
}
void LabelControlNode_Updated(INode node)
{
// Sanity check
if (_nodeMap == null)
{
return;
}
if (_updateWorker.IsBusy || _isUpdating)
{
return;
}
// Update control if it is part of the footer, where visibility appears as false
if (!_forceUpdateEvenIfNotVisible && !IsVisible)
{
return;
}
_updateWorker.RunWorkerAsync(node);
}
#endregion
#region UI_UPDATE
private void UpdateLabelDisplay(INodeMap nodemap, string nodename, IValue node)
{
if (nodemap == null || nodename.Length == 0)
{
return;
}
Type type = node.GetType();
if (type == typeof (Float))
{
if (_floatNode == null)
{
_floatNode = nodemap.GetNode<IFloat>(nodename);
}
SetControlNameLabel(_floatNode.DisplayName);
this._unit = _floatNode.Unit;
if (!_floatNode.IsReadable)
{
return;
}
string temp = "";
if (_mapper != null)
{
temp = _mapper.FormatNodeValueToString(_propertyToControl, "", DecimalPlaces);
}
else
{
temp = NumericFormatter.FormatNumericToString(_floatNode.Value, DecimalPlaces);
}
this.ContentLabel = temp + string.Format("{0}", _unit.Length > 0 ? " " + _unit : "");
}
else if (type == typeof (Integer) || type == typeof (IntReg))
{
if (_integerNode == null)
{
_integerNode = nodemap.GetNode<IInteger>(nodename);
}
SetControlNameLabel(_integerNode.DisplayName);
if (!_integerNode.IsReadable)
{
return;
}
if (_mapper != null)
{
this.ContentLabel = _mapper.FormatNodeValueToString(_propertyToControl);
}
else
{
this.ContentLabel = _integerNode.Value.ToString();
}
}
else
{
if (_node == null)
{
_node = _nodeMap.GetNode<IValue>(nodename);
}
SetControlNameLabel(_node.DisplayName);
if (!_node.IsReadable)
{
return;
}
if (_mapper != null)
{
this.ContentLabel = _mapper.FormatNodeValueToString(_propertyToControl);
}
}
}
public void InvalidateNode()
{
TimeSpan duration = DateTime.Now - lastPollTime;
if (_node != null)
{
long pollTime = _node.PollingTime == -1 ? 2000 : _node.PollingTime;
if (duration.TotalMilliseconds > pollTime)
{
_node.Invalidate();
lastPollTime = DateTime.Now;
}
}
}
public override void Refresh()
{
try
{
_initializing = true;
UpdateLabelDisplay(_nodeMap, _propertyToControl, _node);
}
catch (System.Exception ex)
{
log.Warn(
string.Format(
"{1}Problem retrieving new value from {0} node", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_initializing = false;
}
}
#endregion
#region HELPER
#endregion
}
}
}