I am writing a program which is supposed to detect when a USB serial device is plugged in and then log on to the new com port. The code below works wonderfully, but I have noticed in debugging the code and stepping through it that the event handler "DetectChange" fires twice. I'm not sure that this is normal, or an action of the debugger.
In any case, the code works, but I am new at event handling and I would like to make sure that I am not going to cause any issues as I add more code to actually read and write from the serial port.
(I got some of this code from stackoverflow, but I have misplaced my paper with names for attribution. If you see your code below, my heartfelt thanks.)
using System;
using System.IO.Ports;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Management;
using System.Threading;
namespace SerialTest
{
public partial class Form1 : Form
{
SerialMethods serialMethods = new SerialMethods();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
loadCmdBox();
}
private void CmdBoxPort_SelectedIndexChanged(object sender, EventArgs e)
{
handleComPort();
}
private void handleComPort()
{
// Set the right port for the selected item.
// The portname is based on the "COMx" part of the string (SelectedItem)
string item = CmdBoxPort.SelectedItem.ToString();
// Search for the expression "(COM" in the "selectedItem" string
if (item.Contains("(COM"))
{
// Get the index number where "(COM" starts in the string
int indexOfCom = item.IndexOf("(COM");
// Set PortName to COMx based on the expression in the "selectedItem" string
// It automatically gets the correct length of the COMx expression to make sure
// that also a COM10, COM11 and so on is working properly.
string PortName = item.Substring(indexOfCom + 1, item.Length - indexOfCom - 2);
if (serialMethods._serialPort.IsOpen)
{
serialMethods._serialPort.Close();
serialMethods.Connect(PortName);
label5.Text = "Active Port: " + PortName;
}
else
{
serialMethods.Connect(PortName);
label5.Text = PortName;
}
}
else
return;
}
private void loadCmdBox()
{
// Get all serial (COM)-ports you can see in the devicemanager
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\cimv2",
"SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");
// Sort the items in the combobox
CmdBoxPort.Sorted = true;
// Add all available (COM)-ports to the combobox
foreach (System.Management.ManagementObject queryObj in searcher.Get().Cast<ManagementObject>())
{
CmdBoxPort.Items.Add(queryObj["Caption"]);
}
SerialPortService.PortsChanged += (sender1, changedArgs) => DetectChange(changedArgs.EventType);
label2.Text = "";
label3.Text = "";
label4.Text = "";
}
protected Task<Task> getSerPorts()
{
CmdBoxPort.Text = "";
CmdBoxPort.Update();
if (!String.IsNullOrEmpty(CmdBoxPort.Text))
{
handleComPort();
return Task.FromResult(Task.CompletedTask);
}
else
{
loadCmdBox();
return Task.FromResult(Task.CompletedTask);
}
}
private void ExitButton_Click(object sender, EventArgs e)
{
SerialPortService.CleanUp();
this.Close();
}
private void RefreshButton_Click(object sender, EventArgs e)
{
refresh();
}
protected Task<Task> refresh()
{
label2.Text = "";
label3.Text = "";
label4.Text = "";
CmdBoxPort.Items.Clear();
getSerPorts();
return Task.FromResult(Task.CompletedTask);
}
protected virtual void DetectChange(EventType changedArgs)
{
if (changedArgs == EventType.Insertion)
{
try
{
Task tr = (Task)Invoke(new Action( () => { getSerPorts(); }));
Task rr = (Task)Invoke(new Action(() => { refresh(); }));
}
catch (Exception ex) { MessageBox.Show("Exception at insertion invoke method " + ex, "Exception", MessageBoxButtons.OK); }
}
else if (changedArgs == EventType.Removal)
{
try
{
Task tr = (Task)Invoke(new Action( () => { getSerPorts(); }));
Task rr = (Task)Invoke(new Action(() => { refresh(); }));
}
catch (Exception ex) { MessageBox.Show("Exception at removal invoke method " + ex, "Exception", MessageBoxButtons.OK); }
}
return;
}
}
public static class SerialPortService
{
private static SerialPort _serialPort;
private static string[] _serialPorts;
private static ManagementEventWatcher arrival;
private static ManagementEventWatcher removal;
private static readonly SerialMethods SD = new SerialMethods();
static SerialPortService()
{
_serialPorts = SerialPort.GetPortNames();
MonitorDeviceChanges();
}
public static void CleanUp()
{
arrival.Stop();
removal.Stop();
}
public static event EventHandler<PortsChangedArgs> PortsChanged;
private static void MonitorDeviceChanges()
{
try
{
var deviceArrivalQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
var deviceRemovalQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
arrival = new ManagementEventWatcher(deviceArrivalQuery);
removal = new ManagementEventWatcher(deviceRemovalQuery);
arrival.EventArrived += (o, args) => RaisePortsChangedIfNecessary(EventType.Insertion);
removal.EventArrived += (sender, eventArgs) => RaisePortsChangedIfNecessary(EventType.Removal);
// Start listening for events
arrival.Start();
removal.Start();
}
catch (ManagementException err)
{
MessageBox.Show("Management exception = " + err, "Info", MessageBoxButtons.OK);
}
}
private static void RaisePortsChangedIfNecessary(EventType eventType)
{
lock (_serialPorts)
{
var availableSerialPorts = SerialPort.GetPortNames();
if (eventType == EventType.Insertion)
{
var added = availableSerialPorts.Except(_serialPorts).ToArray();
_serialPorts = availableSerialPorts;
PortsChanged.Raise(null, new PortsChangedArgs(eventType, added));
}
else if (eventType == EventType.Removal)
{
var removed = _serialPorts.Except(availableSerialPorts).ToArray();
_serialPorts = availableSerialPorts;
PortsChanged.Raise(null, new PortsChangedArgs(eventType, removed));
}
}
}
public static void Raise<T>(this EventHandler<T> handler, object sender, T args) where T : EventArgs
{
handler?.Invoke(sender, args);
}
}
public enum EventType
{
Insertion,
Removal,
}
public class PortsChangedArgs : EventArgs
{
private readonly EventType _eventType;
private readonly string[] _serialPorts;
public PortsChangedArgs(EventType eventType, string[] serialPorts)
{
_eventType = eventType;
_serialPorts = serialPorts;
}
public string[] SerialPorts => _serialPorts;
public EventType EventType => _eventType;
}
}
Just took a short look at this. It seems like getSerPorts() will always execute loadCmdBox() (CmdBoxPort.Text = ""; ... if (!String.IsNullOrEmpty(CmdBoxPort.Text))) that will attach a new event handler (previous attached event handlers will not be removed by attaching a new one).
You should either remove the existing event handler befor attaching a new one or only attach the event handler once.
I'm trying to make a command line for my game in Unity and when adding system information commands like memory I encountered this problem. I hope the community can help me. Thanks in advance. The errors occur at lines 216, 223, and 225.
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;
public delegate void CommandHandler(string[] args);
public class ConsoleController {
#region Event declarations
// Used to communicate with ConsoleView
public delegate void LogChangedHandler(string[] log);
public event LogChangedHandler logChanged;
public delegate void VisibilityChangedHandler(bool visible);
public event VisibilityChangedHandler visibilityChanged;
#endregion
/// <summary>
/// Object to hold information about each command
/// </summary>
class CommandRegistration {
public string command { get; private set; }
public CommandHandler handler { get; private set; }
public string help { get; private set; }
public CommandRegistration(string command, CommandHandler handler, string help) {
this.command = command;
this.handler = handler;
this.help = help;
}
}
/// <summary>
/// How many log lines should be retained?
/// Note that strings submitted to appendLogLine with embedded newlines will be counted as a single line.
/// </summary>
const int scrollbackSize = 20;
Queue<string> scrollback = new Queue<string>(scrollbackSize);
List<string> commandHistory = new List<string>();
Dictionary<string, CommandRegistration> commands = new Dictionary<string, CommandRegistration>();
public string[] log { get; private set; } //Copy of scrollback as an array for easier use by ConsoleView
const string repeatCmdName = "!!"; //Name of the repeat command, constant since it needs to skip these if they are in the command history
public ConsoleController() {
//When adding commands, you must add a call below to registerCommand() with its name, implementation method, and help text.
registerCommand("babble", babble, "Example command that demonstrates how to parse arguments. babble [word] [# of times to repeat]");
registerCommand("echo", echo, "echoes arguments back as array (for testing argument parser)");
registerCommand("help", help, "Print this help.");
registerCommand("hide", hide, "Hide the console.");
registerCommand(repeatCmdName, repeatCommand, "Repeat last command.");
registerCommand("reload", reload, "Reload game.");
registerCommand("resetprefs", resetPrefs, "Reset & saves PlayerPrefs.");
registerCommand("ver", ver, "Displays the current game version.");
registerCommand("buildver", buildver, "Displays the current build.");
registerCommand("sys", sys, "Displays basic system information.");
registerCommand("devinfo", devinfo, "Displays important developer information.");
}
void registerCommand(string command, CommandHandler handler, string help) {
commands.Add(command, new CommandRegistration(command, handler, help));
}
public void appendLogLine(string line) {
Debug.Log(line);
if (scrollback.Count >= ConsoleController.scrollbackSize) {
scrollback.Dequeue();
}
scrollback.Enqueue(line);
log = scrollback.ToArray();
if (logChanged != null) {
logChanged(log);
}
}
public void runCommandString(string commandString) {
appendLogLine("$ " + commandString);
string[] commandSplit = parseArguments(commandString);
string[] args = new string[0];
if (commandSplit.Length < 1) {
appendLogLine(string.Format("Unable to process command '{0}'", commandString));
return;
} else if (commandSplit.Length >= 2) {
int numArgs = commandSplit.Length - 1;
args = new string[numArgs];
Array.Copy(commandSplit, 1, args, 0, numArgs);
}
runCommand(commandSplit[0].ToLower(), args);
commandHistory.Add(commandString);
}
public void runCommand(string command, string[] args) {
CommandRegistration reg = null;
if (!commands.TryGetValue(command, out reg)) {
appendLogLine(string.Format("Unknown command '{0}', type 'help' for list.", command));
} else {
if (reg.handler == null) {
appendLogLine(string.Format("Unable to process command '{0}', handler was null.", command));
} else {
reg.handler(args);
}
}
}
static string[] parseArguments(string commandString)
{
LinkedList<char> parmChars = new LinkedList<char>(commandString.ToCharArray());
bool inQuote = false;
var node = parmChars.First;
while (node != null)
{
var next = node.Next;
if (node.Value == '"') {
inQuote = !inQuote;
parmChars.Remove(node);
}
if (!inQuote && node.Value == ' ') {
node.Value = '\n';
}
node = next;
}
char[] parmCharsArr = new char[parmChars.Count];
parmChars.CopyTo(parmCharsArr, 0);
return (new string(parmCharsArr)).Split(new char[] {'\n'} , StringSplitOptions.RemoveEmptyEntries);
}
#region Command handlers
//Implement new commands in this region of the file.
/// <summary>
/// A test command to demonstrate argument checking/parsing.
/// Will repeat the given word a specified number of times.
/// </summary>
void babble(string[] args) {
if (args.Length < 2) {
appendLogLine("Expected 2 arguments.");
return;
}
string text = args[0];
if (string.IsNullOrEmpty(text)) {
appendLogLine("Expected arg1 to be text.");
} else {
int repeat = 0;
if (!Int32.TryParse(args[1], out repeat)) {
appendLogLine("Expected an integer for arg2.");
} else {
for(int i = 0; i < repeat; ++i) {
appendLogLine(string.Format("{0} {1}", text, i));
}
}
}
}
void echo(string[] args) {
StringBuilder sb = new StringBuilder();
foreach (string arg in args)
{
sb.AppendFormat("{0},", arg);
}
sb.Remove(sb.Length - 1, 1);
appendLogLine(sb.ToString());
}
void help(string[] args) {
foreach(CommandRegistration reg in commands.Values) {
appendLogLine(string.Format("{0}: {1}", reg.command, reg.help));
}
}
void hide(string[] args) {
if (visibilityChanged != null) {
visibilityChanged(false);
}
}
void repeatCommand(string[] args) {
for (int cmdIdx = commandHistory.Count - 1; cmdIdx >= 0; --cmdIdx) {
string cmd = commandHistory[cmdIdx];
if (String.Equals(repeatCmdName, cmd)) {
continue;
}
runCommandString(cmd);
break;
}
}
void reload(string[] args) {
Application.LoadLevel(Application.loadedLevel);
}
void resetPrefs(string[] args) {
PlayerPrefs.DeleteAll();
PlayerPrefs.Save();
}
void ver(string[] args) {
appendLogLine("La Llorona 16w14~");
}
void buildver(string[] args)
{
appendLogLine("Build 040916.04");
}
void sys(string[] args)
{
appendLogLine(SystemInfo.operatingSystem);
appendLogLine(SystemInfo.processorType);
appendLogLine(SystemInfo.systemMemorySize);
appendLogLine(SystemInfo.graphicsDeviceName);
}
void devinfo(string[] args)
{
appendLogLine(SystemInfo.deviceModel);
appendLogLine(SystemInfo.deviceType);
appendLogLine(SystemInfo.graphicsDeviceName);
appendLogLine(SystemInfo.graphicsMemorySize);
}
#endregion
}
appendLogLine takes string as the parameter but you are passing int to it with appendLogLine(SystemInfo.systemMemorySize);, appendLogLine(SystemInfo.deviceType); and appendLogLine(SystemInfo.graphicsMemorySize);
You have to convert those integers to strings with ToString(). So those lines should be
appendLogLine(SystemInfo.systemMemorySize.ToString());
appendLogLine(SystemInfo.deviceType.ToString());
appendLogLine(SystemInfo.graphicsMemorySize.ToString());
Also, Application.LoadLevel(Application.loadedLevel); is deprecated so include using UnityEngine.SceneManagement; at the top then change Application.LoadLevel to
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
The fixed version of your code:
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;
public delegate void CommandHandler(string[] args);
public class ConsoleController
{
#region Event declarations
// Used to communicate with ConsoleView
public delegate void LogChangedHandler(string[] log);
public event LogChangedHandler logChanged;
public delegate void VisibilityChangedHandler(bool visible);
public event VisibilityChangedHandler visibilityChanged;
#endregion
/// <summary>
/// Object to hold information about each command
/// </summary>
class CommandRegistration
{
public string command { get; private set; }
public CommandHandler handler { get; private set; }
public string help { get; private set; }
public CommandRegistration(string command, CommandHandler handler, string help)
{
this.command = command;
this.handler = handler;
this.help = help;
}
}
/// <summary>
/// How many log lines should be retained?
/// Note that strings submitted to appendLogLine with embedded newlines will be counted as a single line.
/// </summary>
const int scrollbackSize = 20;
Queue<string> scrollback = new Queue<string>(scrollbackSize);
List<string> commandHistory = new List<string>();
Dictionary<string, CommandRegistration> commands = new Dictionary<string, CommandRegistration>();
public string[] log { get; private set; } //Copy of scrollback as an array for easier use by ConsoleView
const string repeatCmdName = "!!"; //Name of the repeat command, constant since it needs to skip these if they are in the command history
public ConsoleController()
{
//When adding commands, you must add a call below to registerCommand() with its name, implementation method, and help text.
registerCommand("babble", babble, "Example command that demonstrates how to parse arguments. babble [word] [# of times to repeat]");
registerCommand("echo", echo, "echoes arguments back as array (for testing argument parser)");
registerCommand("help", help, "Print this help.");
registerCommand("hide", hide, "Hide the console.");
registerCommand(repeatCmdName, repeatCommand, "Repeat last command.");
registerCommand("reload", reload, "Reload game.");
registerCommand("resetprefs", resetPrefs, "Reset & saves PlayerPrefs.");
registerCommand("ver", ver, "Displays the current game version.");
registerCommand("buildver", buildver, "Displays the current build.");
registerCommand("sys", sys, "Displays basic system information.");
registerCommand("devinfo", devinfo, "Displays important developer information.");
}
void registerCommand(string command, CommandHandler handler, string help)
{
commands.Add(command, new CommandRegistration(command, handler, help));
}
public void appendLogLine(string line)
{
Debug.Log(line);
if (scrollback.Count >= ConsoleController.scrollbackSize)
{
scrollback.Dequeue();
}
scrollback.Enqueue(line);
log = scrollback.ToArray();
if (logChanged != null)
{
logChanged(log);
}
}
public void runCommandString(string commandString)
{
appendLogLine("$ " + commandString);
string[] commandSplit = parseArguments(commandString);
string[] args = new string[0];
if (commandSplit.Length < 1)
{
appendLogLine(string.Format("Unable to process command '{0}'", commandString));
return;
}
else if (commandSplit.Length >= 2)
{
int numArgs = commandSplit.Length - 1;
args = new string[numArgs];
Array.Copy(commandSplit, 1, args, 0, numArgs);
}
runCommand(commandSplit[0].ToLower(), args);
commandHistory.Add(commandString);
}
public void runCommand(string command, string[] args)
{
CommandRegistration reg = null;
if (!commands.TryGetValue(command, out reg))
{
appendLogLine(string.Format("Unknown command '{0}', type 'help' for list.", command));
}
else
{
if (reg.handler == null)
{
appendLogLine(string.Format("Unable to process command '{0}', handler was null.", command));
}
else
{
reg.handler(args);
}
}
}
static string[] parseArguments(string commandString)
{
LinkedList<char> parmChars = new LinkedList<char>(commandString.ToCharArray());
bool inQuote = false;
var node = parmChars.First;
while (node != null)
{
var next = node.Next;
if (node.Value == '"')
{
inQuote = !inQuote;
parmChars.Remove(node);
}
if (!inQuote && node.Value == ' ')
{
node.Value = '\n';
}
node = next;
}
char[] parmCharsArr = new char[parmChars.Count];
parmChars.CopyTo(parmCharsArr, 0);
return (new string(parmCharsArr)).Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
}
#region Command handlers
//Implement new commands in this region of the file.
/// <summary>
/// A test command to demonstrate argument checking/parsing.
/// Will repeat the given word a specified number of times.
/// </summary>
void babble(string[] args)
{
if (args.Length < 2)
{
appendLogLine("Expected 2 arguments.");
return;
}
string text = args[0];
if (string.IsNullOrEmpty(text))
{
appendLogLine("Expected arg1 to be text.");
}
else
{
int repeat = 0;
if (!Int32.TryParse(args[1], out repeat))
{
appendLogLine("Expected an integer for arg2.");
}
else
{
for (int i = 0; i < repeat; ++i)
{
appendLogLine(string.Format("{0} {1}", text, i));
}
}
}
}
void echo(string[] args)
{
StringBuilder sb = new StringBuilder();
foreach (string arg in args)
{
sb.AppendFormat("{0},", arg);
}
sb.Remove(sb.Length - 1, 1);
appendLogLine(sb.ToString());
}
void help(string[] args)
{
foreach (CommandRegistration reg in commands.Values)
{
appendLogLine(string.Format("{0}: {1}", reg.command, reg.help));
}
}
void hide(string[] args)
{
if (visibilityChanged != null)
{
visibilityChanged(false);
}
}
void repeatCommand(string[] args)
{
for (int cmdIdx = commandHistory.Count - 1; cmdIdx >= 0; --cmdIdx)
{
string cmd = commandHistory[cmdIdx];
if (String.Equals(repeatCmdName, cmd))
{
continue;
}
runCommandString(cmd);
break;
}
}
void reload(string[] args)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
void resetPrefs(string[] args)
{
PlayerPrefs.DeleteAll();
PlayerPrefs.Save();
}
void ver(string[] args)
{
appendLogLine("La Llorona 16w14~");
}
void buildver(string[] args)
{
appendLogLine("Build 040916.04");
}
void sys(string[] args)
{
appendLogLine(SystemInfo.operatingSystem);
appendLogLine(SystemInfo.processorType);
appendLogLine(SystemInfo.systemMemorySize.ToString());
appendLogLine(SystemInfo.graphicsDeviceName);
}
void devinfo(string[] args)
{
appendLogLine(SystemInfo.deviceModel);
appendLogLine(SystemInfo.deviceType.ToString());
appendLogLine(SystemInfo.graphicsDeviceName);
appendLogLine(SystemInfo.graphicsMemorySize.ToString());
}
#endregion
}
I've looked through this over and over again, I can't seem to figure out what the issue is. After looking it up some common issue where just people added extra braces or just forgetting one but I've looked through it and cant seem to find where I messed up. What is causing this error and why is it happening? It's showing the errors on lines 120 and 105.
using UnityEngine;
using Rocket.Core.Plugins;
using Rocket.Core.Logging;
using Rocket.Unturned.Events;
using Rocket.Unturned.Player;
using System.Collections.Generic;
using Rocket.Unturned;
using System;
using System.Timers;
namespace VipTeleport
{
public class VipTeleport : RocketPlugin
{
public static VipTeleport Instance;
public Vector3 DeathPos;
public UnturnedPlayer movePlayer;
public bool canTeleport = false;
public int timerT = 0;
public List<string> players = new List<string>();
public List<PlayerFinder> playerVars = new List<PlayerFinder>();
public PlayerFinder playerInfo;
public string steamId;
public int[] playerTimer = new int[24];
public int[] playerSteamID = new int[24];
public bool[] playersCanTeleport = new bool[24];
public int index;
protected override void Load()
{
VipTeleport.Instance = this;
//Just console logs for the plugin in RocketApi on unturneds server console
Logger.LogWarning("##################################");
Logger.LogWarning("#Vip Teleport Loaded Sucessfully!#");
Logger.LogWarning("##################################");
Logger.LogWarning("# Version V.1.0 #");
Logger.LogWarning("##################################");
}
protected override void Unload()
{
}
private void FixedUpdate()
{
U.Events.OnPlayerConnected += (UnturnedPlayer player) =>
{
int addTo = Convert.ToInt32(player.CSteamID);
foreach (int f in playerSteamID)
{
if (f == 0)
{
playerSteamID[f] = addTo;
foreach (int i in playerTimer)
{
playerTimer[f] = 0;
break;
}
foreach (bool t in playersCanTeleport)
{
playersCanTeleport[f] = false;
}
break;
}
}
};
//Listener for player Death
UnturnedPlayerEvents.OnPlayerDead += (UnturnedPlayer player, Vector3 Vector3) =>
{
int localSteamID = Convert.ToInt32(player.CSteamID);
foreach (int i in playerSteamID)
{
if (i == localSteamID)
{
index = i;
playerTimer[index] = 120;
break;
}
}
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(playerTimeVars);
aTimer.Interval = playerTimer[index];
aTimer.Enabled = true;
if ((playerTimer[index] <= 120) && (playerInfo.timerT > 0))
{
playerInfo.canTeleport = true;
}
else
{
playerInfo.canTeleport = false;
playerInfo.timerT = 0;
}
};
U.Events.OnPlayerDisconnected += (UnturnedPlayer player) =>
{
};
public int indexHolder(int i)
{
return i;
}
public void playerTimeVars(object source, ElapsedEventArgs e)
{
int localIndex = indexHolder(index);
playerTimer[localIndex] = 0;
}
}
}
}
Your last two methods need to be below a curly brace, currently they are inside the FixedUpdate() method.
private void FixedUpdate()
{
...
U.Events.OnPlayerDisconnected += (UnturnedPlayer player) =>
{
};
}
public int indexHolder(int i)
{
return i;
}
public void playerTimeVars(object source, ElapsedEventArgs e)
{
int localIndex = indexHolder(index);
playerTimer[localIndex] = 0;
}
Your FixedUpdate() method hasn't got enough brackets.
The methods public int indexHolder(int i), public void playerTimeVars(object source, ElapsedEventArgs e) are placed inside private void FixedUpdate() method which is the source of this error. Place them outside FixedUpdate and it should fix the error
I am creating an application where I have a ListBox which has items that are read in from a text file using StreamReader. I have created a search form but I'm not sure what to do next. Can anyone give me some suggestions please? Here is my code:
My code for the ListBox (sorry it's so long)
public partial class frmSwitches : Form
{
public static ArrayList switches = new ArrayList();
public static frmSwitches frmkeepSwitches = null;
public static string inputDataFile = "LeckySafe.txt";
const int numSwitchItems = 6;
public frmSwitches()
{
InitializeComponent();
frmkeepSwitches = this;
}
private void btnDevices_Click(object sender, EventArgs e)
{
frmDevices tempDevices = new frmDevices();
tempDevices.Show();
frmkeepSwitches.Hide();
}
private bool fileOpenForReadOK(string readFile, ref StreamReader dataIn)
{
try
{
dataIn = new StreamReader(readFile);
return true;
}
catch (FileNotFoundException notFound)
{
MessageBox.Show("ERROR Opening file (when reading data in) - File could not be found.\n"
+ notFound.Message);
return false;
}
catch (Exception e)
{
MessageBox.Show("ERROR Opening File (when reading data in) - Operation failed.\n"
+ e.Message);
return false;
}
}
private bool getNextSwitch(StreamReader inNext, string[] nextSwitchData)
{
string nextLine;
int numDataItems = nextSwitchData.Count();
for (int i = 0; i < numDataItems; i++)
{
try
{
nextLine = inNext.ReadLine();
if (nextLine != null)
nextSwitchData[i] = nextLine;
else
{
return false;
}
}
catch (Exception e)
{
MessageBox.Show("ERROR Reading from file.\n" + e.Message);
return false;
}
}
return true;
}
private void readSwitches()
{
StreamReader inSwitches = null;
Switch tempSwitch;
bool anyMoreSwitches = false;
string[] switchData = new string[numSwitchItems];
if (fileOpenForReadOK(inputDataFile, ref inSwitches))
{
anyMoreSwitches = getNextSwitch(inSwitches, switchData);
while (anyMoreSwitches == true)
{
tempSwitch = new Switch(switchData[0], switchData[1], switchData[2], switchData[3], switchData[4], switchData[5]);
switches.Add(tempSwitch);
anyMoreSwitches = getNextSwitch(inSwitches, switchData);
}
}
if (inSwitches != null) inSwitches.Close();
}
public static bool fileOpenForWriteOK(string writeFile, ref StreamWriter dataOut)
{
try
{
dataOut = new StreamWriter(writeFile);
return true;
}
catch (FileNotFoundException notFound)
{
MessageBox.Show("ERROR Opening file (when writing data out)" +
"- File could not be found.\n" + notFound.Message);
return false;
}
catch (Exception e)
{
MessageBox.Show("ERROR Opening File (when writing data out)" +
"- Operation failed.\n" + e.Message);
return false;
}
}
public static void writeSwitches()
{
StreamWriter outputSwitches = null;
if (fileOpenForWriteOK(inputDataFile, ref outputSwitches))
{
foreach (Switch currSwitch in switches)
{
outputSwitches.WriteLine(currSwitch.getSerialNo());
outputSwitches.WriteLine(currSwitch.getType());
outputSwitches.WriteLine(currSwitch.getInsDate());
outputSwitches.WriteLine(currSwitch.getElecTest());
outputSwitches.WriteLine(currSwitch.getPatId());
outputSwitches.WriteLine(currSwitch.getNumDevice());
}
outputSwitches.Close();
}
if (outputSwitches != null) outputSwitches.Close();
}
private void showListOfSwitches()
{
lstSwitch.Items.Clear();
foreach (Switch b in switches)
lstSwitch.Items.Add(b.getSerialNo()
+ b.getType() + b.getInsDate()
+ b.getElecTest() + b.getPatId() + b.getNumDevice());
}
My code for the search form:
private void btnSearch_Click(object sender, EventArgs e)
{
frmSearchSwitch tempSearchSwitch = new frmSearchSwitch();
tempSearchSwitch.Show();
frmkeepSwitches.Hide();
}
If using a List<T> and lambda is not possible for you then go no farther.
Here I use a List<T> for the data source of a ListBox and mocked up data as where the data comes from is not important but here I am focusing on searching on a property within a class where a select is used to index the items then the where searches in this case) for a specific item, if found the index is used to move to the item. No code present for if not located as this is easy for you to do if the code here is something that is doable for you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace ListBoxSearch_cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
var results =
((List<Item>)ListBox1.DataSource)
.Select((data, index) => new
{ Text = data.SerialNumber, Index = index })
.Where((data) => data.Text == "BB1").FirstOrDefault();
if (results != null)
{
ListBox1.SelectedIndex = results.Index;
}
}
private void Form1_Load(object sender, EventArgs e)
{
var items = new List<Item>() {
new Item {Identifier = 1, SerialNumber = "AA1", Type = "A1"},
new Item {Identifier = 2, SerialNumber = "BB1", Type = "A1"},
new Item {Identifier = 3, SerialNumber = "CD12", Type = "XD1"}
};
ListBox1.DisplayMember = "DisplayText";
ListBox1.DataSource = items;
}
}
/// <summary>
/// Should be in it's own class file
/// but done here to keep code together
/// </summary>
public class Item
{
public string SerialNumber { get; set; }
public string Type { get; set; }
public int Identifier { get; set; }
public string DisplayText
{
get
{
return SerialNumber + " " + this.Type;
}
}
}
}
i built an object to count and log errors. I write the log after a timer elapsed. I don't know how many errors will occur each log period, so i set the List _lastReadErrors to a maximum of 5 errors. In the Full implementation i would like to log some more errors. The logging object should use as less memory as possible. If i put 30 strings in the List, would it make a big difference?
public static class Monitor
{
private static object _syncRoot = new object();
private static DateTime _monitorStart;
private static Timer _logTimer;
private static int _readErrorsAbsolute;
private static List<string> _lastReadErrors;
public Monitor()
{
_monitorStart = DateTime.Now;
_logTimer = new Timer();
_readErrorsAbsolute = 0;
_readErrors = new List<string>();
_logTimer.Elapsed += writeLog;
_logTimer.Interval = 3600000;
_logTimer.AutoReset = true;
_logTimer.Enabled = true;
}
public DateTime MonitorStart
{
get { return _monitorStart; }
}
public int ReadErrorsAbsolute
{
get { return _readErrorsAbsolute; }
}
public void ReadError(Exception ex)
{
Interlocked.Increment(ref _readErrorsAbsolute);
lock (_syncRoot)
{
if (_lastReadErrors.Count > 4) _lastReadErrors.RemoveAt(0);
_lastReadErrors.Add(ex.StackTrace);
}
}
private void writeLog(Object sender, ElapsedEventArgs e)
{
string logString = buildLogString();
// write the logstring into a memorystream
_monitorStart = DateTime.Now;
_readErrorsAbsolute = 0;
lock (_syncRoot)
{
_readErrors = new List<string>();
}
}
private string buildLogString()
{
StringBuilder sb = new StringBuilder();
sb.Append("Date: " + _monitorStart.ToString() + " Errors: " + _readErrorsAbsolute.ToString() + Environment.NewLine);
lock (_syncRoot)
{
foreach (string error in _lastReadErrors)
{
sb.Append(error + Environment.NewLine);
}
}
return sb.ToString();
}
}