if else with checkbox and string - c#

could someone help me figure out what I am doing wrong. I have tried so many ways and can't get it to work in all cases at same time.
Our symbol devices have multiple firmware versions that cause issues with the wireless card in the device. if the firmware version is 86.09.0000 it will work fine. If the firmware version if anything else "01.09.000" it will cause issues so i have it dump a cab file with factory firmware and reboot device.
Thanks for help, below is working code.
if (checkBox1.Checked && myString == "86.09.0000")
{
//check box checked and correct string
}
else if ((checkBox1.Checked == false) && (myString == "86.09.0000"))
{
//check box not checked and correct string
}
else
{
// string doesn't match
}

I would assume you mean if myString isn't 86.09.0000... Is your final else in the wrong 'if' statement?
if (checkBox1.Checked && myString == "86.09.0000")
{
wipefiles();
}
else if ((checkBox1.Checked == false) && (myString == "86.09.0000"))
{
if (myThread == null)
{
label4.Visible = false;
pictureBox1.Enabled = false;
SystemIdleTimerReset();
menuItem1.Enabled = false;
myThread = new Thread(MyWorkerThread);
myThread.IsBackground = true;
myThread.Start();
}
}
else
{
MessageBox.Show("Install firmware");
}
Is this possibly what you were trying to accomplish?

Private void menuItem1_Click(object sender, EventArgs e)
{
String oemVersion = oemver.getOEMVersion();
String myVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
if (myVersion.Equals(oemVersion))
{
if (checkBox1.Checked)
wipefiles();
else
{
if (myThread == null)
{
label4.Visible = false;
pictureBox1.Enabled = false;
SystemIdleTimerReset();
menuItem1.Enabled = false;
myThread = new Thread(MyWorkerThread);
myThread.IsBackground = true;
myThread.Start();
}
}
}
else
{
MessageBox.Show("Install firmware");
}
}

Simply add another "OR" || condition in your if statement .See below
if (checkBox1.Checked && (myString == "86.09.0000"***||myString="01.09.000"***))
{
wipefiles();
}
else if ((checkBox1.Checked == false) && (myString == "86.09.0000"***||myString="01.09.000"***))
{
if (myThread == null)
{
label4.Visible = false;
pictureBox1.Enabled = false;
SystemIdleTimerReset();
menuItem1.Enabled = false;
myThread = new Thread(MyWorkerThread);
myThread.IsBackground = true;
myThread.Start();
}
}
else
{
MessageBox.Show("Install firmware");
}
Now It's working for you ! But it's not good .Because it's maay be going to lot of "OR" condition . So Please assign the mystring value from when code running!

Related

Multi threading hangs UI?

I am using multi threading to make tasks goes faster and smooth, when results increase into richtextbox the UI start hanging don't know why, I creating a webbrowser in thread and doing some other stuff in a single thread kind !
Using Thread as STA ( Single thread kind )
here is a snippet of the code !
foreach (string line in URLLMemoRichTxt.Lines)
{
string href = line;
if (href.Trim() != string.Empty)
{
//XtraMessageBox.Show(href);
if (StopGettingInnerLink == true)
{
AddLog("Getting links has been stopped successfully!");
StopGettingInnerLink = true;
break;
}
else if (StopGettingInnerLink == false)
{
AddLog("Getting links from " + href);
runBrowserThread( new Uri(href));
await Task.Delay(5000);
AddLog("Giving the tool some rest for 5 seconds ! ");
}
}
}
private void runBrowserThread(Uri url)
{
browserth = new Thread(() => {
var br = new WebBrowser();
br.ScriptErrorsSuppressed = true;
br.DocumentCompleted += browser_DocumentCompleted;
br.Navigate(url);
Application.Run();
});
browserth.SetApartmentState(ApartmentState.STA);
browserth.Start();
}
void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var br = sender as WebBrowser;
string currentURL = br.Url.ToString();
if (br.Url == e.Url)
{
HtmlElementCollection acollection = br.Document.GetElementsByTagName("a");
foreach (HtmlElement a in acollection)
{
string href = a.GetAttribute("href");
if (URLLMemoRichTxt.InvokeRequired)
{
URLLMemoRichTxt.Invoke((MethodInvoker)delegate ()
{
if (!URLList.Contains(href) && href.Trim() != string.Empty && !href.Contains(".jpg") && !href.Contains(".png") && !href.Contains(".gif") && !href.Contains(".jpeg"))
{
URLList.Add(href);
// URLListView.Items.Add(href);
// adding new link ino listview !
// URLListCountLBL.Text = URLListView.Items.Count.ToString();
URLLMemoRichTxt.Text += href + "\n";
URLListCountLBL.Text = URLLMemoRichTxt.Lines.Length.ToString();
// runbrowserinthread(href);
}
});
}
else
{
if (!URLList.Contains(href) && href.Trim() != string.Empty && !href.Contains(".jpg") && !href.Contains(".png") && !href.Contains(".gif") && !href.Contains(".jpeg"))
{
URLList.Add(href);
// URLListView.Items.Add(href);
URLLMemoRichTxt.Text += href + "\n";
URLListCountLBL.Text = URLLMemoRichTxt.Lines.Length.ToString();
// GetInnerLink(href);
}
}
}
AddLog("All links has been scrapped successfully for \r\n" + currentURL);
Application.ExitThread(); // Stops the thread
}
}
Already found a solution myself :
replaced :
URLLMemoRichTxt.Text += href + "\n";
With :
URLLMemoRichTxt.AppendText(Environment.NewLine + href);

Serial Communication Port will get Closed after clicking on Close button in C#

I am working on project in C# windows form application.
In this project main Form contain subform for communication of serial port. SubForm "Connect" have two buttons Connect and Close. Also 5 comboboxes to select baudrate, Com name,parity, stopbits and databits.
When I click on Connect button after selecting all settings from comboboxes. port gets connected and connect button becomes Disconnect. And I will close the Connect form
Now my problem is that when I reopen the form, without clicking on Disconnect button when i Close the form , the Comport will disconnected. I don't want that ComPort close.
Please help me to solve this bug. I don't know where I did mistake. Thanks in advance.
Connect Class Code
public partial class Connect : Form
{
public bool Connect_Status = false;
public Connect()
{
InitializeComponent();
COM_List();
}
private void COM_List()
{
for (int i = 0; i < CommPortManager.Instance.GetCommList().Count; i++)
{
cb_CommPort.Items.Add(CommPortManager.Instance.GetCommList()[i]);
}
}
private void btn_Connect_Click(object sender, EventArgs e)
{
if (btn_Connect.Text == "Connect")
{
CommPortManager.Instance.PortName = cb_CommPort.Text;
CommPortManager.Instance.BaudRate = cb_BaudRate.Text;
CommPortManager.Instance.Parity = cb_Parity.Text;
CommPortManager.Instance.StopBits = cb_StopBits.Text;
CommPortManager.Instance.DataBits = cb_DataBits.Text;
if ((cb_CommPort.Text == "") || (cb_BaudRate.Text == "") || (cb_Parity.Text == "") || (cb_DataBits.Text == "") || (cb_StopBits.Text == ""))
{
if (cb_CommPort.Text == "")
{
MessageBox.Show("Please select COM Port and then Connect", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else if (cb_BaudRate.Text == "")
{
MessageBox.Show("Please select BaudRate and then Connect", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else if (cb_Parity.Text == "")
{
MessageBox.Show("Please select Parity and then Connect", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else if (cb_DataBits.Text == "")
{
MessageBox.Show("Please select DataBits and then Connect", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else if(cb_StopBits.Text == "")
{
MessageBox.Show("Please select StopBits and then Connect", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Connect_Status = false;
}
else
{
if (CommPortManager.Instance.COM_Open() == false)
{
MessageBox.Show("Could not open the COM port. Most likely it is already in use, has been removed, or is unavailable.", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information);
Connect_Status = false;
}
else
{
//CommPortManager.Instance.COM_Close();
Connect_Status = true;
btn_Connect.Text = "Disconnect";
cb_CommPort.Enabled = false;
cb_BaudRate.Enabled = false;
cb_DataBits.Enabled = false;
cb_Parity.Enabled = false;
cb_StopBits.Enabled = false;
btn_Connect.BackColor = System.Drawing.Color.Salmon;
}
}
}
else
{
CommPortManager.Instance.COM_Close();
btn_Connect.Text = "Connect";
Connect_Status = false;
cb_CommPort.Enabled = true;
cb_BaudRate.Enabled = true;
cb_DataBits.Enabled = true;
cb_Parity.Enabled = true;
cb_StopBits.Enabled = true;
btn_Connect.BackColor = System.Drawing.Color.DarkTurquoise;
}
}
private void btn_Close_Click(object sender, EventArgs e)
{
this.Close();
}
private void Connect_Load(object sender, EventArgs e)
{
//code here to setup the value;
cb_CommPort.Text = CommPortManager.Instance.PortName;
cb_BaudRate.Text = CommPortManager.Instance.BaudRate;
cb_Parity.Text = CommPortManager.Instance.Parity;
cb_StopBits.Text = CommPortManager.Instance.StopBits;
cb_DataBits.Text = CommPortManager.Instance.DataBits;
if (CommPortManager.Instance.IsOpen == true)
{
btn_Connect.Text = "Disconnect";
btn_Connect.BackColor = System.Drawing.Color.Salmon;
cb_CommPort.Enabled = false;
cb_BaudRate.Enabled = false;
cb_DataBits.Enabled = false;
cb_Parity.Enabled = false;
cb_StopBits.Enabled = false;
}
else
{
btn_Connect.Text = "Connect";
Connect_Status = false;
cb_CommPort.Enabled = true;
cb_BaudRate.Enabled = true;
cb_DataBits.Enabled = true;
cb_Parity.Enabled = true;
cb_StopBits.Enabled = true;
btn_Connect.BackColor = System.Drawing.Color.DarkTurquoise;
}
}
}
I suspect that the form load event. you need to set the connection status true when its open
private void Connect_Load(object sender, EventArgs e)
{
//code here to setup the value;
cb_CommPort.Text = CommPortManager.Instance.PortName;
cb_BaudRate.Text = CommPortManager.Instance.BaudRate;
cb_Parity.Text = CommPortManager.Instance.Parity;
cb_StopBits.Text = CommPortManager.Instance.StopBits;
cb_DataBits.Text = CommPortManager.Instance.DataBits;
if (CommPortManager.Instance.IsOpen == true)
{
Connect_Status = true;
btn_Connect.Text = "Disconnect";
btn_Connect.BackColor = System.Drawing.Color.Salmon;
cb_CommPort.Enabled = false;
cb_BaudRate.Enabled = false;
cb_DataBits.Enabled = false;
cb_Parity.Enabled = false;
cb_StopBits.Enabled = false;
}
else
{
btn_Connect.Text = "Connect";
Connect_Status = false;
cb_CommPort.Enabled = true;
cb_BaudRate.Enabled = true;
cb_DataBits.Enabled = true;
cb_Parity.Enabled = true;
cb_StopBits.Enabled = true;
btn_Connect.BackColor = System.Drawing.Color.DarkTurquoise;
}
}
It looks like that if you press Connect it changes your btn_Connect.Text to
Disconnect (if the port is open)
now the button text is "Disconnect" and if (btn_Connect.Text == "Connect") is now false and the else is called which does CommPortManager.Instance.COM_Close();

How to fire Text.TextChanged event with timer

I do some validations regarding a path (if a file exists or not in the specified directory) and I need to fire up the TextChangedEvent after some time passed after the error to check again for that file.
Here is the code that I use to check for this error:
private void textBoxNovoSvrc_TextChanged(object sender, EventArgs e)
{
First++;
bool ok = false;
int same = 0;
try
{
if (!String.IsNullOrWhiteSpace(textBoxNovoSvrc.Text) && Program.Funcoes.ExisteDirectoria(textBoxNovoSvrc.Text) == true)
{
if (Erro2 == -1 || Erro2 == 0)
same = TextBoxSame(First);
if (same == 1)
return;
if (Global.VersaoInvalidaCli == true && Global.VersaoInvalidaSvrc == true)
{
Global.SvrcChanged = true;
buttonContinuar.PerformClick();
}
if (Program.Funcoes.ExisteFicheiro(textBoxNovoSvrc.Text + #"\OrcaService.exe.config") == true)
{
if (Global.VersaoInvalidaCli == true && Global.VersaoInvalidaSvrc == true)
{
buttonContinuar.PerformClick();
epDoesntExist1.Dispose();
epInvalidVersionSvrc.SetError(textBoxNovoSvrc, "Versão de Update Inválida!");
epInvalidVersionSvrc.Dispose();
epInvalidVersionCli.Dispose();
textBoxNovoCli.Text = Directory.GetParent(textBoxNovoSvrc.Text) + #"\Orca";
return;
}
if (textBox1 == textBoxNovoSvrc.Name || textBox2 == textBoxNovoSvrc.Name)
{
TextBoxes(textBox1, textBox2, true);
}
//Colocar aqui a versão mais recente do update;
string path = Directory.GetParent(textBoxNovoSvrc.Text).ToString();
//string Nome = System.IO.Path.GetFileName(path);
labelNovaVersãoServ.Text = Program.Funcoes.NovaVersao(path, Global.versionError);
Erro2 = 0;
ok = true;
errorProviderNoSvrc.Dispose();
epInvalidVersionSvrc.Dispose();
epDoesntExist2.Dispose();
Global.NovoServiço = textBoxNovoSvrc.Text;
textBoxNovoSvrc.BackColor = System.Drawing.Color.Green;
Continue++;
if (Continue >= 4)
buttonContinuar.Enabled = true;
else
{
buttonContinuar.Enabled = false;
}
btnBrowse2.Enabled = true;
textBoxNovoCli.Enabled = true;
textBoxNovoCli.Text = "";
textBoxNovoCli.Text = Directory.GetParent(textBoxNovoSvrc.Text).ToString() + #"\Orca";
}
else
{
ok = false;
textBoxNovoSvrc.BackColor = System.Drawing.Color.Red;
buttonContinuar.Enabled = false;
Erro2 = 1;
textBoxNovoSvrc.Focus();
epDoesntExist2.Dispose();
epInvalidVersionSvrc.Dispose();
errorProviderNoSvrc.SetError(textBoxNovoSvrc, "Ficheiro \"OrcaService.exe.config\" não existe na directoria");
return;
}
On the last else after errorProviderNoSvrc.SetError(textBoxNovoSvrc, "Ficheiro \"OrcaService.exe.config\" não existe na directoria");I need to fire a timer to wait around 5 seconds before firing up the textChanged event again.
Is this possible to do or do I need to take another aproach such as firing up a message box asking to check again for the file and firing up the TextChanged event "manually" by storing the path on a var and than chaging the text of the textbox like this TexBoxNovoSvrc.Text = "" and than TextBoxNovoSvrc.Text = OldPath.
You can use a timer:
at the begining(outside textBoxNovoSvrc_TextChanged), maybe in constructor
Timer t = new Timer();
t.Interval = 5000;
t.Tick += textBoxNovoSvrc_TextChanged;
Just before the last return
t.Start();
And at the start of textBoxNovoSvrc_TextChanged:
if(t.Enabled){
t.Stop()
}

Process.Start capturing standard output characters

I have a Windows Service that is going to process results from plink.exe (Putty/SSH thing). I'm currently successfully capturing the standard output and sending commands via the standard input to the process.
My problem is, the OutputDataReceived event doesn't seem to get raised until I receive a line break from the console application process. The process prompts for a password and there isn't a line break until after I input a password.
So my question is, is there a way to process the Standard Output character-by-character, instead of line-by-line from the System.Diagnostics.Process class?
Here is my code:
_processInfoTest = new ProcessStartInfo();
_processInfoTest.FileName = serviceSettings.PlinkExecutable;
_processInfoTest.Arguments = GetPlinkArguments(serviceSettings);
_processInfoTest.RedirectStandardOutput = true;
_processInfoTest.RedirectStandardError = true;
_processInfoTest.RedirectStandardInput = true;
_processInfoTest.UseShellExecute = false;
_processInfoTest.CreateNoWindow = true;
_processTest = new Process();
_processTest.StartInfo = _processInfoTest;
_processTest.OutputDataReceived += processTest_OutputDataReceived;
_processTest.ErrorDataReceived += processTest_OutputDataReceived;
_processTest.Start();
_processTest.BeginOutputReadLine();
_processTest.BeginErrorReadLine();
And the event handler that handles the incoming lines of text:
private static void processTest_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string line = e.Data;
if (line != null)
{
WcfServerHelper.BroadcastRemoteCallback(x => x.PlinkTextOutput(line, DateTime.Now));
if (line.Contains("If you do not trust this host, press Return to abandon the"))
{
_processTest.StandardInput.Write("y");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
// This code never gets called because the event doesn't get raised until a line-break occurs
if (line.Contains("'s password:"))
{
_processTest.StandardInput.Write("mypassword");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
if (line.Contains("Access granted"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.Success));
}
else if (line.Contains("Access denied") || line.Contains("Password authentication failed"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.InvalidUserOrPass));
}
else if (line.Contains("Host does not exist"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.InvalidHostname));
}
else if (line.Contains("Connection timed out"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.TimedOut));
}
}
}
Thank you!
the event you are using is line buffered ... you will have to implement your own reader that calls Read() / ReadAsync() on the streamreader to get every char ...
I was looking for an answer forever, and right after asking the question here I found my solution.
Btw, thanks DarkSquirrel, you hit the nail on the head.
Here is my solution:
_processInfoTest = new ProcessStartInfo();
_processInfoTest.FileName = serviceSettings.PlinkExecutable;
_processInfoTest.Arguments = GetPlinkArguments(serviceSettings);
_processInfoTest.RedirectStandardOutput = true;
_processInfoTest.RedirectStandardError = true;
_processInfoTest.RedirectStandardInput = true;
_processInfoTest.UseShellExecute = false;
_processInfoTest.CreateNoWindow = true;
WcfServerHelper.BroadcastRemoteCallback(x => x.PlinkTextOutput(_processInfoTest.Arguments, DateTime.Now));
_processTest = new Process();
_processTest.StartInfo = _processInfoTest;
_processTest.Start();
Task.Factory.StartNew(() =>
{
ProcessOutputCharacters(_processTest.StandardError);
});
Task.Factory.StartNew(() =>
{
ProcessOutputCharacters(_processTest.StandardOutput);
});
And my methods:
private static void ProcessOutputCharacters(StreamReader streamReader)
{
int outputCharInt;
char outputChar;
string line = string.Empty;
while (-1 != (outputCharInt = streamReader.Read()))
{
outputChar = (char)outputCharInt;
if (outputChar == '\n' || outputChar == '\r')
{
if (line != string.Empty)
{
ProcessLine("Output: " + line);
}
line = string.Empty;
}
else
{
line += outputChar;
if (line.Contains("login as:"))
{
_processTest.StandardInput.Write("myusername");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
if (line.Contains("'s password:"))
{
_processTest.StandardInput.Write("mypassword");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
}
}
}
private static void ProcessLine(string line)
{
if (line != null)
{
WcfServerHelper.BroadcastRemoteCallback(x => x.PlinkTextOutput(line, DateTime.Now));
if (line.Contains("If you do not trust this host, press Return to abandon the"))
{
_processTest.StandardInput.Write("y");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
if (line.Contains("Access granted"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.Success));
}
else if (line.Contains("Access denied") || line.Contains("Password authentication failed"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.InvalidUserOrPass));
}
else if (line.Contains("Host does not exist"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.InvalidHostname));
}
else if (line.Contains("Connection timed out"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.TimedOut));
}
}
}
My only problem now is when I send the username or password (through StandardInput), it's only sending the first 5 characters. I'll do some research on the issue and post that as a separate question if I need to.
Thanks!

Handling errors while inside a button

I have a windows form that involes filling out textboxes with information and then clicking connect. I have error messages that pops up if any of the textboxes are empty but when I hit OK the program just continues and I end up getting run-time errors because there's insufficient information, and the program crashes. What I want is for the program to go back to the point before I hit "Connect" whenever any textbox is not filled out correctly.
This is the code:
private void cmdConnect_Click(object sender, EventArgs e)
{
if (cmdConnect.Text == "Connect")
{
if (txtGroup.Text == "")
{
txtGroup.Text = "_Group01";
}
if (txtItemID.Text == "")
{
MessageBox.Show("Please enter ItemID.", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
switch (cboServer.Text)
{
case "":
MessageBox.Show("Please select and OPC server", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "RSLinx Remote OPC Server":
if (txtMachine.Text == "")
{
MessageBox.Show("Please enter a machine name for remote connection", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
}
else
{
oOpcServer.Connect(cboServer.Text, txtMachine.Text);
}
break;
case "RSLinx OPC Server":
oOpcServer.Connect(cboServer.Text);
break;
default:
if (txtMachine.Text == "")
{
oOpcServer.Connect(cboServer.Text);
}
else
{
oOpcServer.Connect(cboServer.Text, txtMachine.Text);
}
break;
}
oOpcGroup = oOpcServer.OPCGroups.Add(txtGroup.Text);
oOpcGroup.IsSubscribed = true;
oOpcGroup.IsActive = false;
oOpcGroup.UpdateRate = 1000;
ClHandle = 1;
oOpcGroup.OPCItems.DefaultAccessPath = txtAccessPath.Text;
oOpcGroup.OPCItems.AddItem(txtItemID.Text, ClHandle);
cmdItemWrite.Enabled = true;
cmdItemRead.Enabled = true;
cmdSyncWrite.Enabled = true;
cmdSyncRead.Enabled = true;
cmdAsyncWrite.Enabled = true;
cmdAsyncRead.Enabled = true;
cmdAdvise.Enabled = true;
txtSubValue.Enabled = true;
cboServer.Enabled = false;
txtMachine.Enabled = false;
txtGroup.Enabled = false;
txtAccessPath.Enabled = false;
txtItemID.Enabled = false;
cmdConnect.Text = "Disconnect";
}
else
{
oOpcServer.OPCGroups.RemoveAll();
oOpcGroup = null;
oOpcServer.Disconnect();
cmdConnect.Text = "Connect";
cmdItemWrite.Enabled = false;
cmdItemRead.Enabled = false;
cmdSyncWrite.Enabled = false;
cmdSyncRead.Enabled = false;
cmdAsyncWrite.Enabled = false;
cmdAsyncRead.Enabled = false;
cmdAdvise.Enabled = false;
txtSubValue.Enabled = false;
cboServer.Enabled = true;
txtMachine.Enabled = true;
txtGroup.Enabled = true;
txtAccessPath.Enabled = true;
txtItemID.Enabled = true;
}
oOpcGroup.DataChange += new RsiOPCAuto.DIOPCGroupEvent_DataChangeEventHandler(oOpcGroup_DataChange);
}
Adding a return statment after each message box would do the trick and cause the method to exit without doing the work at end.
Simplest solution, as Dervall mentioned is adding return statements after each MessageBox.Show call. But more elegant solution is using validation and error provider to highlight incorrect input data prior to executing connect logic.
Anyway, here is some thoughts on refactoring your code.
private void cmdConnect_Click(object sender, EventArgs e)
{
if (cmdConnect.Text == "Disconnect")
{
Disconnect();
SetControlsToDisconnectedState();
return;
}
if (String.IsNullOrWhiteSpace(txtGroup.Text))
txtGroup.Text = "_Group01";
if (String.IsNullOrWhiteSpace(txtItemID.Text))
{
ShowErrorMessage("Connect Error", "Please enter ItemID.");
return;
}
if (String.IsNullOrWhiteSpace(cboServer.Text))
{
ShowErrorMessage("Connect Error", "Please select and OPC server");
return;
}
Connect(cboServer.Text, txtMachine.Text);
DoSomethingWithGroup(txtGroup.Text, txtAccessPath.Text, txtItemID.Text);
SetControlsToConnectedState();
}
What changed:
It's more readable, when you verify which text on button, then which it don't have
Method ShowErrorMessage does exactly what it says
Verify text with IsNullOrWhiteSpace because it could be full of white spaces
Control state changing moved to separate code
Connecting/Disconnecting now separated from UI
Here other methods:
private void ShowErrorMessage(string title, string message)
{
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void SetControlsToConnectedState()
{
UpdateControls(true);
}
private void SetControlsToDisconnectedState()
{
UpdateControls(false);
}
private void UpdateControls(bool isConnected)
{
cmdConnect.Text = isConnected ? "Disconnect" : "Connect";
cmdItemWrite.Enabled = isConnected;
cmdItemRead.Enabled = isConnected;
cmdSyncWrite.Enabled = isConnected;
cmdSyncRead.Enabled = isConnected;
cmdAsyncWrite.Enabled = isConnected;
cmdAsyncRead.Enabled = isConnected;
cmdAdvise.Enabled = isConnected;
txtSubValue.Enabled = isConnected;
cboServer.Enabled = !isConnected;
txtMachine.Enabled = !isConnected;
txtGroup.Enabled = !isConnected;
txtAccessPath.Enabled = !isConnected;
txtItemID.Enabled = !isConnected;
}
private void Disconnect()
{
oOpcServer.OPCGroups.RemoveAll();
oOpcGroup = null;
oOpcServer.Disconnect();
}
private void Connect(string serverName, string machineName)
{
switch (serverName)
{
case "RSLinx Remote OPC Server":
if (String.IsNullOrWhiteSpace(machineName))
{
ShowErrorMessage("Connect Error", "Please enter a machine name for remote connection");
return;
}
oOpcServer.Connect(serverName, machineName);
break;
case "RSLinx OPC Server":
oOpcServer.Connect(serverName);
break;
default:
if (String.IsNullOrWhiteSpace(machineName))
oOpcServer.Connect(serverName);
else
oOpcServer.Connect(serverName, machineName);
break;
}
}
private void DoSomethingWithGroup(string groupName, string accessPath, string itemID)
{
oOpcGroup = oOpcServer.OPCGroups.Add(groupName);
oOpcGroup.IsSubscribed = true;
oOpcGroup.IsActive = false;
oOpcGroup.UpdateRate = 1000;
ClHandle = 1;
oOpcGroup.OPCItems.DefaultAccessPath = accessPath;
oOpcGroup.OPCItems.AddItem(itemID, ClHandle);
oOpcGroup.DataChange += new RsiOPCAuto.DIOPCGroupEvent_DataChangeEventHandler(oOpcGroup_DataChange);
}

Categories

Resources