File RadioButtonControl.xaml.cs¶
File List > PGRControls > RadioButtonControl.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 SpinnakerNET.GenApi;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace SpinnakerNET.GUI
{
namespace WPFControls
{
public sealed partial class RadioButtonControl : BaseClass
{
#region FIELDS
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(RadioButtonControl));
private IEnum _enumNode;
private Dictionary<string, long>_entryTable;
private Dictionary<string, RadioButton>_buttonTable;
private bool _disposed = false;
// GenICam callback update thread
BackgroundWorker _updateWorker;
#endregion
#region Constructor
public RadioButtonControl()
{
InitializeComponent();
_entryTable = new Dictionary<string, long>();
_buttonTable = new Dictionary<string, RadioButton>();
_updateWorker = new BackgroundWorker();
_updateWorker.DoWork += _updateWorker_DoWork;
_updateWorker.RunWorkerCompleted += _updateWorker_RunWorkerCompleted;
}
~RadioButtonControl()
{
Disconnect();
}
internal RadioButtonControl(RadioButtonControl originalControl)
{
InitializeComponent();
_entryTable = new Dictionary<string, long>();
_buttonTable = new Dictionary<string, RadioButton>();
_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.Visibility);
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)
{
}
// Consider GenICam callbacks as unmanaged resource
Disconnect();
_disposed = true;
}
// Call Dispose in the base class.
base.Dispose(disposing);
}
#endregion
#region ICAMERACONTROL
public override void Connect(INodeMap nodemap, string nodename, string namelabel = "")
{
if (nodename.Length != 0 && nodemap != null)
{
_initializing = true;
// Acquire device serial number
if (string.IsNullOrWhiteSpace(_serialNumber))
{
_serialNumber = RetrieveSerialNumber(nodemap);
}
// Acquire device model name
if (string.IsNullOrWhiteSpace(_deviceModelName))
{
_deviceModelName = RetrieveModelName(nodemap);
}
try
{
this._nodeMap = nodemap;
this._propertyToControl = nodename;
_enumNode = nodemap.GetNode<IEnum>(this._propertyToControl);
if (_enumNode == null)
{
throw new Exception("Feature not found");
}
this._nodeType = _enumNode.GetType();
if (namelabel.Length > 0)
{
SetControlNameLabel(namelabel);
SetNameLabelVisibility(System.Windows.Visibility.Visible);
}
else
{
SetControlNameLabel(_enumNode.DisplayName);
}
_enumNode.Updated += new NodeEventHandler(enumNode_Updated);
if (_enumNode != null && _enumNode.IsReadable)
{
CreateRadioButtons();
}
_featureAvailable = _enumNode.IsImplemented;
RegisterInterfaceEvents();
}
catch (System.Exception ex)
{
_featureAvailable = false;
log.Debug(
string.Format(
"{1}Problem accessing {0} node. {2}",
this._propertyToControl,
FormattedSerialNumber,
ex.Message),
ex);
throw new Exception(string.Format(
"{2}Problem accessing {0} node. {1}",
this._propertyToControl,
ex.Message,
FormattedSerialNumber));
}
finally
{
_initializing = false;
}
}
else
{
}
}
public override void Disconnect()
{
try
{
if (_enumNode != null)
{
_enumNode.Updated -= new NodeEventHandler(enumNode_Updated);
_enumNode = null;
}
_mapper = null;
base.Disconnect();
}
catch (System.Exception /*ex*/)
{
}
}
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;
_enumNode = _nodeMap.GetNode<IEnum>(this._propertyToControl);
if (_enumNode != null && _enumNode.IsReadable)
{
rootPanel.IsEnabled = true;
CreateRadioButtons();
}
else
{
rootPanel.IsEnabled = false;
}
}
catch (System.Exception /*ex*/)
{
}
finally
{
_initializing = false;
}
}
#endregion
#region EVENT_HANDLERS
void timer_Tick(object sender, EventArgs e)
{
try
{
Refresh();
}
catch (System.Exception /*ex*/)
{
Debug.WriteLine(string.Format("Problem retrieving new value from {0} node", _propertyToControl));
}
}
private void RadioButton_Click(object sender, RoutedEventArgs e)
{
if (_initializing)
{
return;
}
if (_enumNode != null && _enumNode.IsWritable)
{
RadioButton button = (RadioButton) sender;
long buttonValue = 0;
if (_entryTable.TryGetValue(button.Content.ToString(), out buttonValue))
{
// Unchecked all buttons
foreach(KeyValuePair<string, RadioButton>pair in _buttonTable)
{
pair.Value.IsChecked = false;
}
button.IsChecked = true;
//_skipCallback = true;
_enumNode.Value = buttonValue;
//_skipCallback = false;
}
}
}
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
private void
_updateWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
_isUpdating = true;
_initializing = 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);
if (currentNodeStatus.IsReadable)
{
rootPanel.IsEnabled = true;
CreateRadioButtons();
}
else
{
rootPanel.IsEnabled = false;
}
}
catch (System.Exception ex)
{
log.Debug(
string.Format(
"{1}Problem updating control for {0} node", _propertyToControl, FormattedSerialNumber),
ex);
}
finally
{
_initializing = false;
_isUpdating = false;
}
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 enumNode_Updated(INode node)
{
if (_nodeMap == null)
{
return;
}
if (_updateWorker.IsBusy || _isUpdating)
{
return;
}
if (!IsVisible)
{
return;
}
_updateWorker.RunWorkerAsync(node);
}
#endregion
#region HELPER
void CreateRadioButtons()
{
string[] symbolics = _enumNode.Symbolics;
_entryTable.Clear();
_buttonTable.Clear();
rootPanel.Children.Clear();
for (int i = 0; i < _enumNode.Entries.Length; i++)
{
// Keep track of all possible entries and their Node value
_entryTable.Add(_enumNode.Entries[i], _enumNode.Entries[i].Value);
}
foreach(var s in _enumNode.Entries)
{
RadioButton button = new RadioButton();
button.Content = s.Symbolic;
if (s.ToolTip != null && s.ToolTip.Length > 0)
{
button.ToolTip = s.ToolTip;
}
button.Click += new RoutedEventHandler(RadioButton_Click);
_buttonTable.Add(s, button);
rootPanel.Children.Add(button);
// Entry could be unavailable on device
// Let's check Symbolic array to verify
if (symbolics.Contains(s.Symbolic))
{
button.IsEnabled = true;
}
else
{
button.IsEnabled = false;
}
}
// Entries and Symbolic sometimes do not contain
// same number of items. As a result, we need to
// search symbolic list to find corresponding index
// for current node value
int index = 0;
foreach(string s in symbolics)
{
if (_enumNode.Value.String.Equals(s))
{
RadioButton tempButton = new RadioButton();
if (_buttonTable.TryGetValue(s, out tempButton))
{
tempButton.IsChecked = true;
}
break;
}
index++;
}
}
#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
}
}
}