File CheckboxControl.xaml.cs¶
File List > PGRControls > CheckboxControl.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 System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using SpinnakerNET.GenApi;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Threading;
namespace SpinnakerNET.GUI
{
namespace WPFControls
{
public sealed partial class CheckboxControl : BaseClass
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(CheckboxControl));
private static readonly log4net.ILog analytics = log4net.LogManager.GetLogger("Analytics");
#region FIELDS
private bool _labelAppearLeft = false;
private bool _skipCallback = false;
private bool _disposed = false;
// GenICam callback update thread
BackgroundWorker _updateWorker;
#endregion
#region PROPERTIES
public bool LabelAppearLeft
{
get
{
return _labelAppearLeft;
}
set
{
_labelAppearLeft = value;
if (value)
{
this.checkbox.FlowDirection = FlowDirection.RightToLeft;
}
else
{
this.checkbox.FlowDirection = FlowDirection.LeftToRight;
}
}
}
#endregion
#region Constructor
public CheckboxControl()
{
InitializeComponent();
this.DataContext = this;
_timer = new System.Windows.Forms.Timer();
_dependencyStringList = new List<string>();
_dependencyControlList = new CameraControlCollection();
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
}
~CheckboxControl()
{
Disconnect();
}
internal CheckboxControl(CheckboxControl originalControl)
{
InitializeComponent();
this.DataContext = this;
_timer = new System.Windows.Forms.Timer();
_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.ControlVisibility);
this.SetControlID(originalControl.ControlID);
this.SetMin(originalControl.GetMin());
this.SetMax(originalControl.GetMax());
this.SetControlNameLabel(originalControl.ControlNameLabel);
this.SetNameLabelVisibility(originalControl.GetNameLabelVisibility());
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());
}
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
Disconnect();
}
_disposed = true;
}
// Call Dispose in the base class.
base.Dispose(disposing);
}
#endregion
#region ICAMERACONTROL_INTERFACE
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 Refresh()
{
try
{
_initializing = true;
if (_boolNode != null && _boolNode.IsReadable)
{
if (checkbox.IsChecked != _boolNode.Value)
{
_skipCallback = true;
checkbox.IsChecked = _boolNode.Value;
_skipCallback = false;
}
}
else
{
_skipCallback = true;
checkbox.IsChecked = null;
_skipCallback = false;
}
UpdateControlStatus();
}
catch (System.Exception /*ex*/)
{
Debug.WriteLine(string.Format("Problem retrieving new value from {0} node", _propertyToControl));
}
finally
{
_initializing = false;
}
}
public override void SetControlNameLabel(string namelabel)
{
if (namelabel == null)
{
return;
}
if (namelabel.Length > 0)
{
ControlNameLabel = namelabel;
}
else
{
if (_boolNode != null)
{
ControlNameLabel = _boolNode.DisplayName;
}
}
}
public override void SetNameLabelVisibility(System.Windows.Visibility visibility)
{
if (visibility == System.Windows.Visibility.Collapsed || visibility == System.Windows.Visibility.Hidden)
{
checkbox.Content = "";
}
else
{
checkbox.Content = _controlNameLabel;
}
}
public override System.Windows.Visibility GetNameLabelVisibility()
{
if (checkbox.Content.ToString().Length > 0)
{
return System.Windows.Visibility.Visible;
}
else
{
return System.Windows.Visibility.Collapsed;
}
}
public override void Connect(INodeMap nodemap, string nodename, string namelabel = "")
{
if (nodename == string.Empty || nodemap == null)
{
return;
}
this._propertyToControl = nodename;
this._nodeMap = nodemap;
// Acquire device serial number
if (string.IsNullOrWhiteSpace(_serialNumber))
{
_serialNumber = RetrieveSerialNumber(nodemap);
}
// Acquire device model name
if (string.IsNullOrWhiteSpace(_deviceModelName))
{
_deviceModelName = RetrieveModelName(nodemap);
}
try
{
IValue node = nodemap.GetNode<IValue>(nodename);
if (node == null)
{
throw new Exception("Feature not found");
}
if (node.GetType() != typeof (BoolNode))
{
_featureAvailable = false;
// Not a IBool node
log.Error(string.Format("{1}{0} is not a Bool node", nodename, FormattedSerialNumber));
throw new Exception(
string.Format("{1}{0} is not a Bool node", nodename, FormattedSerialNumber));
}
this._nodeType = node.GetType();
_boolNode = _nodeMap.GetNode<IBool>(nodename);
_featureAvailable = _boolNode.IsImplemented;
UpdateCheckBoxStatus(_boolNode);
// Update backstore
this.ControlNameLabel = namelabel;
// Push update to UI explicitly
SetControlNameLabel(ControlNameLabel);
SetToolTip(_boolNode.ToolTip.ToString());
UpdateControlStatus();
_boolNode.Updated += boolNode_Updated;
_callbackRegistered = true;
// RegisterInterfaceEvents();
}
catch (System.Exception ex)
{
_featureAvailable = false;
log.Debug(
string.Format("{1}Problem accessing {0} node.", this._propertyToControl, FormattedSerialNumber),
ex);
throw new Exception(
string.Format("Problem accessing {0} node. {1}", this._propertyToControl, ex.Message));
}
finally
{
}
}
public override void Disconnect()
{
try
{
if (_boolNode != null && _callbackRegistered)
{
_boolNode.Updated -= boolNode_Updated;
}
_boolNode = null;
_mapper = null;
_callbackRegistered = false;
base.Disconnect();
}
catch (System.Exception /*ex*/)
{
}
}
#endregion
#region GENICAM_EVENTS
[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;
}
try
{
Dispatcher.Invoke(() => {
_initializing = true;
_skipCallback = true;
_isUpdating = true;
INode node = e.Result as INode;
NodeStatus currentNodeStatus = new NodeStatus(node);
if (currentNodeStatus.ExceptionObject != null)
{
return;
}
string logMessage =
string.Format("Spinnaker Callback: Feature=\"{0}\"", currentNodeStatus.NodeName);
logMessage += string.Format(", Value=\"{0}\"", currentNodeStatus.CurrentStringValue);
LogNodeCallback(log, currentNodeStatus.NodeName, logMessage);
ControlNameLabel = currentNodeStatus.NodeDisplayName;
// Update checkbox status
if (currentNodeStatus.IsReadable)
{
if (checkbox.IsChecked != currentNodeStatus.CurrentBooleanValue)
{
checkbox.Checked -= checkbox_Checked;
checkbox.IsChecked = currentNodeStatus.CurrentBooleanValue;
checkbox.Checked += checkbox_Checked;
refreshRequired = true;
}
}
else
{
checkbox.Checked -= checkbox_Checked;
checkbox.IsChecked = null;
checkbox.Checked += checkbox_Checked;
refreshRequired = true;
}
// Update UI Enabled Appearance
if (IsEditable && (!currentNodeStatus.IsImplemented || !currentNodeStatus.IsAvailable ||
!currentNodeStatus.IsReadable))
{
IsEditable = false;
this.checkbox.IsEnabled = false;
}
// Node becomes non-writable
if (IsEditable && !currentNodeStatus.IsWritable)
{
IsEditable = false;
this.checkbox.IsEnabled = false;
}
// Node becomes writable
if (!IsEditable && currentNodeStatus.IsWritable)
{
IsEditable = true;
if (!this.checkbox.IsEnabled)
{
this.checkbox.IsEnabled = true;
}
refreshRequired = true;
}
});
}
catch (System.Exception ex)
{
log.Debug(
string.Format(
"{1}Problem updating control for {0} node", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_initializing = false;
_skipCallback = 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;
}
private void boolNode_Updated(INode node)
{
if (_initializing || _skipCallback)
{
return;
}
if (_nodeMap == null)
{
return;
}
if (_updateWorker.IsBusy || _isUpdating)
{
return;
}
if (!IsVisible)
{
return;
}
_updateWorker.RunWorkerAsync(node);
}
#endregion
#region UI_UPDATE
private void UpdateCheckBoxStatus(IBool node)
{
_initializing = true;
try
{
if (node != null && node.IsReadable)
{
_skipCallback = true;
checkbox.IsChecked = _boolNode.Value;
_skipCallback = false;
}
}
catch (System.Exception /*ex*/)
{
}
finally
{
_initializing = false;
}
}
private void UpdateControlStatus()
{
if (_nodeMap == null)
{
IsEditable = false;
this.checkbox.IsEnabled = false;
return;
}
try
{
IValue node = _nodeMap.GetNode<IValue>(_propertyToControl);
if (node == null || !node.IsImplemented || !node.IsAvailable || !node.IsReadable)
{
IsEditable = false;
this.checkbox.IsEnabled = false;
return;
}
if (!node.IsWritable)
{
IsEditable = false;
this.checkbox.IsEnabled = false;
return;
}
else
{
IsEditable = true;
if (!this.checkbox.IsEnabled)
{
this.checkbox.IsEnabled = true;
}
}
}
catch (Exception ex)
{
Debug.Print("Problem updating Checkbox {0}: {1}", _propertyToControl, ex.Message);
}
}
#endregion
#region EVENT_HANDLER
private void checkbox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
e.Handled = true;
}
}
private void timer_Tick(object sender, EventArgs e)
{
Refresh();
}
private void checkbox_Checked(object sender, RoutedEventArgs e)
{
if (_initializing || _boolNode == null)
{
return;
}
try
{
_skipCallback = true;
// Log user initiated changes
LogNodeUpdateAction(log, _boolNode, "True");
AnalyticsNodeUpdateAction(analytics, _boolNode, "True");
_boolNode.Value = true;
_skipCallback = false;
// Update Dependency
if (_dependencyControlList != null && _dependencyControlList.Count > 0)
{
_dependencyControlList.Refresh();
}
}
catch (System.Exception /*ex*/)
{
Debug.WriteLine("There was a problem writting to {0} node in PGRCheckBox", _propertyToControl);
}
}
private void checkbox_Unchecked(object sender, RoutedEventArgs e)
{
if (_initializing || _boolNode == null)
{
return;
}
try
{
_skipCallback = true;
// Log user initiated changes
LogNodeUpdateAction(log, _boolNode, "False");
AnalyticsNodeUpdateAction(analytics, _boolNode, "False");
_boolNode.Value = false;
_skipCallback = false;
// Update Dependency
if (_dependencyControlList != null && _dependencyControlList.Count > 0)
{
_dependencyControlList.Refresh();
}
}
catch (System.Exception /*ex*/)
{
Debug.WriteLine("There was a problem writting to {0} node in PGRCheckBox", _propertyToControl);
}
}
#endregion
#region ORIENTATION_CONTROL
public override Orientation ContentOrientation
{
get
{
return rootLayout.Orientation;
}
set
{
rootLayout.Orientation = value;
}
}
public void SetContentOrientation(Orientation newOrientation)
{
this.ContentOrientation = newOrientation;
}
public Orientation GetContentOrientation()
{
return this.ContentOrientation;
}
#endregion
}
}
}