Can only display array by iterating through a for loop - c#

Hello I am trying to make a C# program that downloads files but I am having trouble with the array.
I have it split up the text for downloading and put it into a 2 level jagged array (string[][]).
Now I split up the rows up text by the | char so each line will be formatted like so:
{filename}|{filedescription}|{filehttppath}|{previewimagepath}|{length}|{source}
when I use short test text to put it into a text box it displays fine in the text box.
IE: a string like test|test|test|test|test|test
but if I put in a real string that I would actually be using for the program to DL files the only way I get the string to display is to iterate through it with a for or foreach loop. If I try to access the data with the index I get an index missing error. (IE array[0])
So this is the code that gets the array to display:
public Form2(string[][] textList, string path)
{
InitializeComponent();
textBox1.Text = textBox1.Text + path + Environment.NewLine;
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
for(int j=0;j<i.Length;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
}
}
And then this is the code that gives an index missing error:
public Form2(string[][] textList, string path)
{
InitializeComponent();
textBox1.Text = textBox1.Text + path + Environment.NewLine;
WebClient downloader = new WebClient();
foreach (string[] i in textList)
{
textBox1.Text = textBox1.Text + i[0] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[1] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[2] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[3] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[4] + Environment.NewLine;
textBox1.Text = textBox1.Text + i[5] + Environment.NewLine;
}
}
Any help is this is apreciated I don't see why I can access they data through a for loop but not directly it just doesn't make any sense to me.
Also, here is the code that generates the array:
public String[][] finalList(string[] FileList)
{
String[][] FinalArray = new String[FileList.Length][];
for (int i = 0; i<FinalArray.Length;i++)
{
string[] fileStuff = FileList[i].Split(new char[] {'|'});
FinalArray[i] = fileStuff;
}
return FinalArray;
}

In your first example you are using the actual length of each inner array to do the concatenation. In your second example you are hard coded to the same length yet you said in the intro it was a jagged array.
Can you show what your input text looks like?
you are not doing the same concatenation in first and second example so the resulting stings are very different.
first = "\r\n Crazy Video\r\n\\\\newline\r\nThis Video is absolutly crazy!\r\n\\\\newline\r\nhtt://fakeurl.fake/vidfolder/video.flv\r\n\\\\newline\r\nhtt://fakeurl.fake/imgfolder/img.j‌​pg\r\n\\\\newline\r\n300\r\n\\\\newline\r\nhtt://fakeurl.fake \r\n\\\\newline\r\n"
second = "\r\n Crazy Video\r\nThis Video is absolutly crazy!\r\nhtt://fakeurl.fake/vidfolder/video.flv\r\nhtt://fakeurl.fake/imgfolder/img.j‌​pg\r\n300\r\nhtt://fakeurl.fake \r\n"
using System;
using NUnit.Framework;
namespace ClassLibrary5
{
public class Class1
{
[Test]
public void test()
{
var temp = new[]
{
" Crazy Video|This Video is absolutly crazy!|htt://fakeurl.fake/vidfolder/video.flv|htt://fakeurl.fake/imgfolder/img.j‌​pg|300|htt://fakeurl.fake "
};
var final = finalList(temp);
var first = Form1(final, "path");
var second = Form2(final, "path");
Assert.IsTrue(first.CompareTo(second) == 0);
}
public string Form1(string[][] textList, string path)
{
string textString = path + Environment.NewLine;
foreach (string[] i in textList)
{
for (int j = 0; j < i.Length; j++)
{
textString = textString + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
}
return textString;
}
public string Form2(string[][] textList, string path)
{
string textString = path + Environment.NewLine;
foreach (string[] i in textList)
{
textString = textString + i[0] + Environment.NewLine;
textString = textString + i[1] + Environment.NewLine;
textString = textString + i[2] + Environment.NewLine;
textString = textString + i[3] + Environment.NewLine;
textString = textString + i[4] + Environment.NewLine;
textString = textString + i[5] + Environment.NewLine;
}
return textString;
}
public String[][] finalList(string[] FileList)
{
String[][] FinalArray = new String[FileList.Length][];
for (int i = 0; i < FinalArray.Length; i++)
{
string[] fileStuff = FileList[i].Split(new char[] {'|'});
FinalArray[i] = fileStuff;
}
return FinalArray;
}
}
}

Are you sure each String[] in string[][] textList has 6 elements?

Try to replace:
for(int j=0;j<i.Length;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
with:
for(int j=0;j<6;j++)
{
textBox1.Text = textBox1.Text + i[j] + Environment.NewLine + #"\\newline" + Environment.NewLine;
}
And see if you get the same result. Your middle one has different logic than your first one. To troubleshoot, first make the logic the same, and then continue troubleshooting from there.

Related

How can I do a header for a CSV using StringBuilder? C#

I will edit my post because I couldn't express very well.
I want to do this:
This
And I don't know how to do a unique header. I achieved this:
Achieved
but now I need to do the header. I will post more of my code here:
protected override void OnBarUpdate()
{
if (BarsInProgress != 0)
return;
if (CurrentBars[0] < Shift)
return;
string header = "Time" + ";" + "Close[0]" + ";" + "ATR_7" + ";" + "VOL_7" + ";" + "LABEL";
string Label = "NULL";
if(Alcista)
{
if(Open[0] >= Open[Shift - 1] && Open[0]/Open[Shift - 1] >= 1.0001)
{
Label = "UP";
}
else
{
Label = "DOWN";
}
}
switch(Indicar2_Sesgo)
{
case Sesgo.Alcista:
StringBuilder csvcontent = new StringBuilder();
csvcontent.AppendLine(Convert.ToString(Times[0][0].TimeOfDay + ";" + Close[0] + ";" + ATR1[0] + ";" + VOL1[0] + ";" + Label));
string csvpath = "D:\\xyz.csv";
File.AppendAllText(csvpath, csvcontent.ToString());
break;
}
}
It is a little difficult to know what your output is supposed to look like, but if you are simply trying to write a header, your code may look something like this:
var csvPath = "D:\\xyz.csv";
var csvHeader = "Time;Close;Atr1;Atr2";
File.WriteAllText(csvPath, csvHeader + Environment.NewLine);
As others have mentioned you would be better off using a helper library (like csvhelper) and setting the delimiter to a semicolon.

ArgumentOutOfRangeException when I think my code should work

I'm working on a bit of code for school but I keep getting an ArgumentOutOfRangeException
With this code I'm trying to read some data from a .csv file and if it equals the name of the image I want it to remove it from the .csv file whilst keeping the structure intact.
public void checkPair(Image card1, Image card2)
{
this.Image1 = card1;
this.Image2 = card2;
if (Convert.ToString(card1.Source) == Convert.ToString(card2.Source) && (card1 != card2))
{
getPoint(card1, card2);
string path = #"Save1.csv";
var reader = new StreamReader(File.OpenRead(path));
var data = new List<List<string>>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
data.Add(new List<String> { values[0], values[1]
});
}
reader.Close();
string delimiter = ";";
for (int i = 1; i < 5; i++)
{
for (int x = 0; x < 4; x++)
{
if (data[i][x] == Convert.ToString(card1.Source))
{
data[i][x] = null;
}
}
}
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] + Environment.NewLine + data[1][0] + delimiter + data[1][1] + delimiter + data[1][2] + delimiter + data[1][3] + Environment.NewLine + data[2][0] + delimiter + data[2][1] + delimiter + data[2][2] + delimiter + data[2][3] + Environment.NewLine + data[3][0] + delimiter + data[3][1] + delimiter + data[3][2] + delimiter + data[3][3] + Environment.NewLine + data[4][0] + delimiter + data[4][1] + delimiter + data[4][2] + delimiter + data[4][3] + Environment.NewLine + "ready");
I have no idea why I get this error and how to fix it
Initially, I'd change your last line from
File.WriteAllText(path, data[0][0] + delimiter + data[0][1] ....
to something like
var obj1 = data[0][0];
var obj2 = data[0][1];
File.WriteAllText(path, obj1 + delimiter + obj2 .... etc)
If you over inline functions or array accessing, when you get an exception the stack trace won't be that helpful. At least you'll have an idea of the statement that caused the issue.
This technique can prove to be very helpful, if you are looking at an in exception in the logs, after the fact.

how to copy multiple line from text file C#

I need to copy multiple lines from text file(cisco config file): based on the below condition
if the line starts with interface copy from interface until '! '
my file is like :
!
access-list 1>
!
interface 1
ip address xx.xx.xx.xx
!
interface 2
ip address xx.xx.xx.xx
!
route 1
!
I try the below code :
var lines = File.ReadAllLines("C:\\My File2.txt");
foreach (var line1 in lines){
string firstWord = line1.Split(' ').First();
if ((firstWord == "access-list") && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (firstWord == "nat")
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
else if (firstWord == "interface")
{
var result = lines.Substring(line1.LastIndexOf('!') + 1);
TextBox3.Text = TextBox3.Text + "\r\n" + result;
}
but I get only one line as output
In case you want to keep your algorithm, this will work for you.
var lines = File.ReadAllLines("C:\\My File2.txt");
int i;
for (i = 0; i<lines.Length;i++)
{
var line1 = lines[i];
if (line1 == "!" || line1 == " ") continue;
if (line1.StartsWith("access-list")) && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (line1.StartsWith("nat"))
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
if (line1.StartsWith("interface"))
{
var str = line1;
while (!Equals(lines[i + 1], "!"))
{
str += lines[i + 1];
i++;
}
TextBox3.Text = TextBox3.Text + "\r\n" + str;
}
}
As per the file structure shown by you interface and ip address are on different lines. So you won't get it in same iteration of for loop. When you find that firstWord == "interface" you will need to set a flag that will tell you that next line is ip address and in next iteration check if that flag is true parse the current line as ip address and process it the way you want.
You should use "File.ReadAllText" instead of "File.ReadAllLines". "File.ReadAllText" returns a string with the complete text file text. After that, you can use the "String.Split" method to generate a string array.
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
Each index of "seperatedStrings" contains what you want.
UPDATE: Here is a code snippet, that can help:
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
foreach (var oneString in seperatedStrings)
{
if (oneString.Contains("access-list"))
{
Console.WriteLine("Access-List: " + oneString);
}else if (oneString.Contains("nat"))
{
Console.WriteLine("Nat: " + oneString);
}else if (oneString.Contains("interface"))
{
Console.WriteLine("Interface: " + oneString);
}
}
This is the output of my code snippet:

How do I fill a text box using a public string?

I have this frustrating problem that I can't seem to solve.
I try to fill a TextBox with text from a public static string.
But when I run the program it just shows a blank text box with nothing in it.
I don't have any errors so it's hard for me to understand what I'm doing wrong.
Here is the code I have:
public ShowMp3()
{
InitializeComponent();
OverzichttxtBox.Text = OverzichtMP3();
}
public static String OverzichtMP3()
{
String overzicht = "";
foreach (Mp3Player player in Mp3.GetPlayers())
overzicht = overzicht + "ID: " + Convert.ToString(player.id) + "\r\n" +
"Merk: " + player.make + "\r\n" + "Model: " + player.model +
"\r\n" + "MB-size: " + player.mBSize + "\r\n" + "Prijs: " +
player.price + "\r\n" + "\r\n";
return overzicht;
}
And Mp3.GetPlayers() is this:
private static ArrayList players = new ArrayList();
public static void Initialize()
{
Mp3Player player1 = new Mp3Player(1, "GET Technologies .inc", "HF 410", 4096, 129.95M, 500);
Mp3Player player2 = new Mp3Player(2, "Far & Loud", "XM 600", 8192, 224.95M, 500);
Mp3Player player3 = new Mp3Player(3, "Innotivative ", "Z3", 512, 79.95M, 500);
Mp3Player player4 = new Mp3Player(4, "Resistance S.A.", "3001", 4096, 124.95M, 500);
Mp3Player player5 = new Mp3Player(5, "CBA", "NXT Volume", 2048, 159.05M, 500);
players.Add(player1);
players.Add(player2);
players.Add(player3);
players.Add(player4);
players.Add(player5);
}
public static ArrayList GetPlayers()
{
return players;
}
I suspect the problem is you're never calling Mp3.Initialize(). You could add this to a static constructor in the Mp3 class:
private static List<Mp3Player> players = new List<Mp3Player>();
static Mp3()
{
Initialize();
}
// This can be private now...
private static void Initialize()
{
....
Note that you may want to change the ArrayList to a List<Mp3Player>, as well.
Also, as an aside, you should give StringBuilder and String.Format a try. Instead of this...
overzicht = overzicht + "ID: " + Convert.ToString(player.id) + "\r\n" +
"Merk: " + player.make + "\r\n" + "Model: " + player.model +
"\r\n" + "MB-size: " + player.mBSize + "\r\n" + "Prijs: " +
player.price + "\r\n" + "\r\n";
You can do:
StringBuilder overzicht = new StringBuilder();
overzicht.AppendLine(String.Format("ID: {0}", player.id));
overzicht.AppendLine(String.Format("Merk: {0}", player.make));
overzicht.AppendLine(String.Format("Model: {0}", player.model));
overzicht.AppendLine(String.Format("MB-size: {0}", player.mBSize));
overzicht.AppendLine(String.Format("Prijs: {0}", player.price));
return overzicht.ToString();
Much easier to read ;)
My String.Format isn't that compelling here... but if this was all on one line, it'd be much more useful:
return String.Format("ID:{0}, Merk:{1}, Model:{2}, MB-size:{3}, Prijs:{4}",
player.id, player.make, player.mode,
player.mBSize, player.price);

Null Reference : Object reference not set to an instance of an object

I have a code for serial communication, with this code im sending values from textboxes to an device or when im testing to another PC. But when I press my "Program" button I get this error.
System.NullReferenceException was unhandled
Object reference not set to an instance of an object.
And i can catch the exception with an try catch but then i wont send my values to the device connected to my port.
This is my code:
public partial class MainForm : Form
{
private Settings _settings;
private SettingsIniFile _settingsIniFile = new SettingsIniFile();
private StringList _baudratelist = new StringList();
private StringList _systemPorts = new StringList();
private StringList _comportList = new StringList();
private Timer _comtimer = new Timer();
private ComPort _comport;
public MainForm()
{
InitializeComponent();
SetBaudrate();
LoadSettings(false);
LoadTextBoxes();
LoadComportName();
_comtimer.Tick += OnComtimerOnTick;
_comtimer.Interval = 2000;
_comtimer.Start();
LoadComportName();
Thread.Sleep(1000);
var portname = GetCurrentComPort();
if (portname != null)
{
_comport = new ComPort("COM6", 9600);
}
//var portname = GetCurrentComPort();
}
private String GetCurrentComPort()
{
int index = _comPortComboBox.SelectedIndex;
if (index < 0)
return null;
return _comportList[index];
}
private void OnComtimerOnTick(object sender, EventArgs args)
{
foreach (var item in SerialPort.GetPortNames())
{
if (!_systemPorts.Contains(item))
{
_comtimer.Stop();
_systemPorts.Add(item);
LoadComportName();
//MessageBox.Show("The new device is connected to" + item);
_comtimer.Start();
}
}
}
private void LoadSettings(bool defaults)
{
SettingsIniFile iniFile = new SettingsIniFile();
_settings = iniFile.LoadSettings(defaults);
}
private void SaveSettings()
{
SaveTextBoxes();
_settingsIniFile.Save(_settings);
}
private void LoadTextBoxes()
{
//ACR
_startRemovalTextBox.Text = _settings.AcrStartRemoval11;
_removalTimeTextBox.Text = _settings.AcrRemovalTime12;
_removalDelayTextBox.Text = _settings.AcrRemovalDelay13;
//CLEANING
_durCleaningTextbox.Text = _settings.CleanDurCleaning21;
_timeValveOnTextbox.Text = _settings.CleanTimeValveOn22;
_timeValveOffTextBox.Text = _settings.CleanTimeValveOff23;
//CALIBRATE
_contentLeftTextBox.Text = _settings.CalibrateContentLeft31;
_calibrateLeftTextBox.Text = _settings.CalibrateCalibrateLeft33;
_contentRightTextBox.Text = _settings.CalibrateContentRight32;
_calibrateRightTextBox.Text = _settings.CalibrateCalibrateRight34;
//CONDUCTIVITY
_factorLeftTextBox.Text = _settings.ConductFactorLeft41;
_offsetLeftTextBox.Text = _settings.ConductOffsetleft42;
_factorRightTextBox.Text = _settings.ConductFactorRight43;
_offsetRightTextBox.Text = _settings.ConductOffsetRight44;
_levelLeftTextBox.Text = _settings.ConductLevelLeft45;
_levelRightTextBox.Text = _settings.ConductLevelRight46;
//GENERAL
_typeOfValveTextBox.Text = _settings.GeneralTypeOfValve51;
_indicatorTextBox.Text = _settings.GeneralIndicator52;
_inverseOutputTextBox.Text = _settings.GeneralInverseOutput53;
_restartTimeTextBox.Text = _settings.GeneralRestartTime54;
_waterTimeTextBox.Text = _settings.GeneralWaterTime55;
_gateDelayTextbox.Text = _settings.GeneralGateDelay56;
//PULSATION
_pulsationTextBox.Text = _settings.PulsationPulsationPm61;
_ratioFrontTextBox.Text = _settings.PulsationSrRatioFront62;
_ratioBackTextBox.Text = _settings.PulsationSrRatioBack63;
_stimulationTextBox.Text = _settings.PulsationStimulationPm64;
_stimFrontTextBox.Text = _settings.PulsationSrStimFront65;
_stimBackTextBox.Text = _settings.PulsationSrStimBack66;
_stimulationDurTextBox.Text = _settings.PulsationStimulationDur67;
//return _settings;
}
private void SaveTextBoxes()
{
//ACR
_settings.AcrStartRemoval11 = _startRemovalTextBox.Text;
_settings.AcrRemovalTime12 = _removalTimeTextBox.Text;
_settings.AcrRemovalDelay13 = _removalDelayTextBox.Text;
//CLEANING
_settings.CleanDurCleaning21 = _durCleaningTextbox.Text;
_settings.CleanTimeValveOn22 = _timeValveOnTextbox.Text;
_settings.CleanTimeValveOff23 = _timeValveOffTextBox.Text;
//CALIBRATE
_settings.CalibrateContentLeft31 = _contentLeftTextBox.Text;
_settings.CalibrateCalibrateLeft33 = _calibrateLeftTextBox.Text;
_settings.CalibrateContentRight32 = _contentRightTextBox.Text;
_settings.CalibrateCalibrateRight34 = _calibrateRightTextBox.Text;
//CONDUCTIVITY
_settings.ConductFactorLeft41 = _factorLeftTextBox.Text;
_settings.ConductOffsetleft42 = _offsetLeftTextBox.Text;
_settings.ConductFactorRight43 = _factorRightTextBox.Text;
_settings.ConductOffsetRight44 = _offsetRightTextBox.Text;
_settings.ConductLevelLeft45 = _levelLeftTextBox.Text;
_settings.ConductLevelRight46 = _levelRightTextBox.Text;
//GENERAL
_settings.GeneralTypeOfValve51 = _typeOfValveTextBox.Text;
_settings.GeneralIndicator52 = _indicatorTextBox.Text;
_settings.GeneralInverseOutput53 = _inverseOutputTextBox.Text;
_settings.GeneralRestartTime54 = _restartTimeTextBox.Text;
_settings.GeneralWaterTime55 = _waterTimeTextBox.Text;
_settings.GeneralGateDelay56 = _gateDelayTextbox.Text;
//PULSATION
_settings.PulsationPulsationPm61 = _pulsationTextBox.Text;
_settings.PulsationSrRatioFront62 = _ratioFrontTextBox.Text;
_settings.PulsationSrRatioBack63 = _ratioBackTextBox.Text;
_settings.PulsationStimulationPm64 = _stimulationTextBox.Text;
_settings.PulsationSrStimFront65 = _stimFrontTextBox.Text;
_settings.PulsationSrStimBack66 = _stimBackTextBox.Text;
_settings.PulsationStimulationDur67 = _stimulationDurTextBox.Text;
}
private void DefaultSettingButtonClick(object sender, System.EventArgs e)
{
LoadSettings(true);
LoadTextBoxes();
SaveSettings();
LoadComportName();
}
private void SendSettingsButtonClick(object sender, System.EventArgs e)
{
var availablePorts = _systemPorts;
if (availablePorts != null && availablePorts.Any())
{
SaveSettings();
SendMessageTest();
}
else
{
_comPortComboBox.Text = "No Ports are available";
}
}
private void LoadComportName()
{
var availablePorts = _systemPorts;
_comPortComboBox.DataSource = null;
if (availablePorts != null && availablePorts.Any())
{
_comPortComboBox.DataSource = availablePorts;
}
else
{
_comPortComboBox.Text = "No Ports are available";
}
}
private void SetBaudrate()
{
_baudratelist.Add("4600");
_baudratelist.Add("9600");
_baudratelist.Add("19200");
}
private void SendMessageTest()
{
var Acrcontent = "[" + _acrNameLabel.Text + "]" + "\r\n" + _acrIdLabel11.Text + _startRemovalTextBox.Text + "\r\n"
+ _acrIdLabel12.Text + _removalTimeTextBox.Text + "\r\n" + _acrIdLabel13.Text +
_removalDelayTextBox.Text + "\r\n";
var Cleaningcontent ="["+ _cleaningNamelLabel.Text+"]" +"\r\n"+_cleaningIdLabel21.Text+
_durCleaningTextbox.Text + "\r\n"+ _cleaningLabelId22.Text+
_timeValveOnTextbox.Text + "\r\n"+ _cleaningLabelId23.Text+_timeValveOffTextBox.Text+"\r\n";
var Calibratecontent = "[" +_calibrateNameLabel.Text+ "]"+"\r\n"+_calibrateIDLabel31.Text+_contentLeftTextBox.Text+
"\r\n"+ _calibrateIDLabel32.Text+_calibrateLeftTextBox.Text+"\r\n"+_calibrateIDLabel33.Text+_contentRightTextBox.Text+
"\r\n" + _calibrateIDLabel34.Text + _calibrateRightTextBox.Text + "\r\n";
var Conductcontent = "[" + _conductName.Text + "]" + "\r\n" + _conductIdLabel41.Text + _factorLeftTextBox.Text +
"\r\n"
+ _conductIdLabel42.Text + _offsetLeftTextBox.Text + "\r\n" + _conductIdLabel43.Text +
_factorRightTextBox.Text + "\r\n"
+ _conductIdLabel44.Text + _offsetRightTextBox.Text + "\r\n" + _conductIdLabel45.Text +
_levelLeftTextBox.Text + "\r\n"
+ _conductIdLabel46.Text + _levelRightTextBox.Text + "\r\n";
var Generalcontent = "[" + _generalName.Text + "]" + "\r\n" + _generalIdLabel51.Text + _typeOfValveTextBox.Text +
"\r\n" +
_generalIdLabel52.Text + _indicatorTextBox.Text + "\r\n" + _generalIdLabel53.Text +
_inverseOutputTextBox.Text +
"\r\n" + _generalIdLabel54.Text + _restartTimeTextBox.Text + "\r\n" +
_generalIdLabel55.Text + _waterTimeTextBox.Text +
"\r\n" + _generalIdLabel56.Text + _gateDelayTextbox.Text + "\r\n";
var Pulsationcontent = "[" + _pulsationName.Text + "]" + "\r\n" + _pulsationIdLabel61.Text +
_pulsationTextBox.Text + "\r\n" +
_pulsationIdLabel62.Text + _ratioFrontTextBox.Text + "\r\n" +
_pulsationIdLabel63.Text + _ratioBackTextBox.Text + "\r\n" +
_pulsationIdLabel64.Text + _stimulationTextBox.Text + "\r\n" +
_pulsationIdLabel65.Text + _stimFrontTextBox.Text + "\r\n" +
_pulsationIdLabel66.Text + _stimBackTextBox.Text + "\r\n" + _pulsationIdLabel67.Text +
_stimulationDurTextBox.Text + "\r\n";
byte[] array = ComPort.StringToBytes(2+"\r\n"+Acrcontent+"\r\n"+Cleaningcontent + "\r\n" + Calibratecontent+"\r\n"+Conductcontent+"\r\n"+Generalcontent+"\r\n"+Pulsationcontent+3);
try
{
_comport.WriteBytes(array);
}
catch(Exception exc)
{
MessageBox.Show("Error {1}: "+ exc);
}
try
{
_comport.ReadBytes(array, array.Length, 1000);
}
catch(Exception exc)
{
MessageBox.Show("Error {2}" + exc);
}
//string result = Encoding.ASCII.GetString(array);
//MessageBox.Show(result);
}
}
This is my code for the communication:
namespace Communication
{
public class ComPort
{
private readonly SerialPort _serialPort;
public ComPort(string portname, int baudRate)
{
_serialPort = new SerialPort();
_serialPort.PortName = portname; <-----
_serialPort.BaudRate = baudRate;
_serialPort.StopBits = StopBits.One;
_serialPort.DataBits = 8;
_serialPort.Parity = Parity.None;
_serialPort.Handshake = Handshake.None;
// _serialPort.WriteBufferSize = 1;
_serialPort.DtrEnable = true;
_serialPort.RtsEnable = true;
_serialPort.Open();
_serialPort.ReadTimeout = 20000;
_serialPort.WriteTimeout = 20000;
}
public void Clear()
{
while (ReadByte() != -1)
continue;
}
private byte[] _array = new byte[] {0};
public void WriteByte(byte value)
{
_array[0] = value;
_serialPort.Write(_array, 0, 1);
// _serialPort.BaseStream.WriteByte(value);
_serialPort.BaseStream.Flush();
}
public void WriteBytes(byte[] array)
{
_serialPort.Write(array, 0, array.Length);
}
public void WriteBytes(byte[] array, int index, int length )
{
_serialPort.Write(array, index, length);
}
private int _readTimeOut = -1;
public int ReadByte(int timeOut = 200)
{
if (timeOut != _readTimeOut)
_serialPort.ReadTimeout = _readTimeOut = timeOut;
try
{
//return _serialPort.BaseStream.ReadByte();
return _serialPort.ReadByte();
// _serialPort.Read(array, 0, 1);
// return array[0];
}
catch (TimeoutException)
{
return -1;
}
}
public int ReadBytes(byte[] array, int length, int timeOut = 200)
{
if (timeOut != _readTimeOut)
_serialPort.ReadTimeout = _readTimeOut = timeOut;
try
{
//return _serialPort.BaseStream.ReadByte();
int bytesRead = 0;
while ( bytesRead < length )
bytesRead += _serialPort.Read(array, bytesRead, length - bytesRead);
// _serialPort.Read(array, 0, 1);
// return array[0];
return bytesRead;
}
catch (TimeoutException)
{
return -1;
}
}
/// <summary>
/// sends string followed by CR - LF
/// </summary>
/// <param name="line"></param>
public void WriteLine(String line)
{
WriteBytes(StringToBytes(line + "\r\n"));
}
public static byte[] StringToBytes(string input)
{
return Encoding.ASCII.GetBytes(input);
}
public void Close()
{
try
{
_serialPort.DtrEnable = false;
_serialPort.RtsEnable = false;
_serialPort.Close();
}
catch(IOException)
{
}
}
public bool Dtr
{
get { return _serialPort.DtrEnable; }
set { _serialPort.DtrEnable = value; }
}
public bool Rts
{
get { return _serialPort.RtsEnable; }
set { _serialPort.RtsEnable = value; }
}
}
}
Can someone explain to me what the problem is?
Thanks in advance
Possible anwser:
InitializeComponent();
SetBaudrate();
LoadSettings(false);
LoadTextBoxes();
LoadComportName();
_comtimer.Tick += OnComtimerOnTick;
_comtimer.Interval = 2000;
_comtimer.Start();
LoadComportName();
Thread.Sleep(1000);
var portname = GetCurrentComPort();
_comport = new ComPort("COM6", 9600);
But when i do this another error comes around the corner:
Value cannot be null.
Parameter name: PortName
This comes in the second piece of code where the arrow is.
Probably there is not comport selected at startup, so the _comport never gets created, you should check if the comport is created before you use is: if (_comport != null) ...
Update:
I think you should create a button instead of default connecting on a combobox selection change.
public void buttonConnect_Click(object sender, EventArgs e)
{
// check if the comport is created, else show a message and return,
TryDisconnect();
var portname = GetCurrentComPort();
if (portname == null)
return;
try
{
_comport = new ComPort(portname, 9600);
}
catch(Exception exception)
{
// try to create a better message here :-)
MessageBox.Show("Something went wrong....");
}
}
public void buttonDisconnect_Click(object sender, EventArgs e)
{
TryDisconnect();
}
public void TryDisconnect()
{
if( _comport != null)
{
_comport.Dispose();
_comport = null;
}
}
Also for this:
private void SendSettingsButtonClick(object sender, System.EventArgs e)
{
// check the _comPort instance first, if not assigned, leave a message..
if(_comPort == null)
{
MessageBox.Show("The comport is not initialized");
return;
}
var availablePorts = _systemPorts;
if (availablePorts != null && availablePorts.Any())
{
SaveSettings();
SendMessageTest();
}
else
{
_comPortComboBox.Text = "No Ports are available";
}
}
I got a tip for you, try to separate the markup/construction of the message, here how you could do.
I did not change all the code, only some examples:
I would create a struct/class to hold all information
public struct AcrContentInfo
{
public string AcrName;
public string AcrId11;
public string StartRemoval;
public string AcrId12;
public string RemovalTime;
public string AcrId13;
public string RemovalDelay;
// markup the information:
public override string ToString()
{
return string.Format(
"[{0}]\r\n{1}{2}\r\n{3}{4}\r\n{5}{6}\r\n",
AcrName,
AcrId11, StartRemoval,
AcrId12, RemovalTime,
AcrId13, RemovalDelay);
}
}
private void SendMessageTest()
{
// Instead of:
//var Acrcontent = "[" + _acrNameLabel.Text + "]" + "\r\n" + _acrIdLabel11.Text + _startRemovalTextBox.Text + "\r\n"
// + _acrIdLabel12.Text + _removalTimeTextBox.Text + "\r\n" + _acrIdLabel13.Text +
// _removalDelayTextBox.Text + "\r\n";
// I would use this instead, this way it wil be easier to maintain different versions.
// The code using the struct isn't responsible for markup
// Create the struct and fillin the fields.
AcrContentInfo acrContentInfo = new AcrContentInfo
{
AcrName = _acrNameLabel.Text,
AcrId11 = _acrIdLabel11.Text,
StartRemoval = _startRemovalTextBox.Text,
AcrId12 = _acrIdLabel12.Text,
RemovalTime = _removalTimeTextBox.Text,
AcrId13 = _acrIdLabel13.Text,
RemovalDelay = _removalDelayTextBox.Text
};
// if there is a new version of the protocol, you can create something like this
// AcrContentInfoV2 acrContentInfo = new AcrContentInfoV2
// call the tostring, (create a markup)
var Acrcontent = acrContentInfo.ToString();
// --- old code ---
var Cleaningcontent = "[" + _cleaningNamelLabel.Text + "]" + "\r\n" + _cleaningIdLabel21.Text +
_durCleaningTextbox.Text + "\r\n" + _cleaningLabelId22.Text +
_timeValveOnTextbox.Text + "\r\n" + _cleaningLabelId23.Text + _timeValveOffTextBox.Text + "\r\n";
var Calibratecontent = "[" + _calibrateNameLabel.Text + "]" + "\r\n" + _calibrateIDLabel31.Text + _contentLeftTextBox.Text +
"\r\n" + _calibrateIDLabel32.Text + _calibrateLeftTextBox.Text + "\r\n" + _calibrateIDLabel33.Text + _contentRightTextBox.Text +
"\r\n" + _calibrateIDLabel34.Text + _calibrateRightTextBox.Text + "\r\n";
var Conductcontent = "[" + _conductName.Text + "]" + "\r\n" + _conductIdLabel41.Text + _factorLeftTextBox.Text +
"\r\n"
+ _conductIdLabel42.Text + _offsetLeftTextBox.Text + "\r\n" + _conductIdLabel43.Text +
_factorRightTextBox.Text + "\r\n"
+ _conductIdLabel44.Text + _offsetRightTextBox.Text + "\r\n" + _conductIdLabel45.Text +
_levelLeftTextBox.Text + "\r\n"
+ _conductIdLabel46.Text + _levelRightTextBox.Text + "\r\n";
var Generalcontent = "[" + _generalName.Text + "]" + "\r\n" + _generalIdLabel51.Text + _typeOfValveTextBox.Text +
"\r\n" +
_generalIdLabel52.Text + _indicatorTextBox.Text + "\r\n" + _generalIdLabel53.Text +
_inverseOutputTextBox.Text +
"\r\n" + _generalIdLabel54.Text + _restartTimeTextBox.Text + "\r\n" +
_generalIdLabel55.Text + _waterTimeTextBox.Text +
"\r\n" + _generalIdLabel56.Text + _gateDelayTextbox.Text + "\r\n";
var Pulsationcontent = "[" + _pulsationName.Text + "]" + "\r\n" + _pulsationIdLabel61.Text +
_pulsationTextBox.Text + "\r\n" +
_pulsationIdLabel62.Text + _ratioFrontTextBox.Text + "\r\n" +
_pulsationIdLabel63.Text + _ratioBackTextBox.Text + "\r\n" +
_pulsationIdLabel64.Text + _stimulationTextBox.Text + "\r\n" +
_pulsationIdLabel65.Text + _stimFrontTextBox.Text + "\r\n" +
_pulsationIdLabel66.Text + _stimBackTextBox.Text + "\r\n" + _pulsationIdLabel67.Text +
_stimulationDurTextBox.Text + "\r\n";
// instad of:
//byte[] array = ComPort.StringToBytes(2+"\r\n"+Acrcontent+"\r\n"+Cleaningcontent + "\r\n" + Calibratecontent+"\r\n"+Conductcontent+"\r\n"+Generalcontent+"\r\n"+Pulsationcontent+3);
// I always try not to make very long lines of code.
// A stringbuilder is much more efficient building strings.
// I would:
StringBuilder sb = new StringBuilder();
sb.AppendLine("2");
sb.AppendLine("Acrcontent");
sb.AppendLine("Cleaningcontent");
sb.AppendLine("Calibratecontent");
sb.AppendLine("Conductcontent");
sb.AppendLine("Generalcontent");
sb.AppendLine("Pulsationcontent");
sb.AppendLine("3");
// why make the comport class responsible for the encoding type. _ComPort.StringToBytes_
byte[] array = Encoding.UTF8.GetBytes(sb.ToString());
try
{
_comport.WriteBytes(array);
// only read when write was succeed?
_comport.ReadBytes(array, array.Length, 1000);
}
catch (Exception exc)
{
MessageBox.Show("Error {1}: " + exc);
}
}
These are only my ideas, and meant to be constructive. (other point of view) Happy codeing..
You have to instantiate _comport before calling a method or accessing a property on it.
maybe in
var portname = GetCurrentComPort();
if (portname != null)
{
_comport = new ComPort("COM6", 9600);
}
portname is null then _comport not instantiated. you can trace it and check that if it has a value or not.
Yes assign a value to _comport like
_comport=null;

Categories

Resources