I am making a darts scoring program and one of the functionalities I would like to add would be all the potential finishes. I have a csv with all the darts finishes, for example if player 1 has 170 left to score the program would look through the csv and output T20,T20,BULL to a specific textbox. I have achieved this using Powershell on a different GUI, I have looked at quite a few similar questions but still haven't figured out a way to do this. below is my Powershell script (might be irrelevant)
$radioButton4_Click = {
$textbox4.text = ""
$text = $textbox2.text
$CSV = Import-Csv "$Dartsfinishes\DartsFinishes.csv"
ForEach($score in $CSV){
if($score.result -like $text){
$textbox4.text = $score.Outcome
}Else{
}
}
}
This is as far as I have got from reading online. I can see similarities between both.
private void textBox5_TextChanged(object sender, EventArgs e, string path)
{
string fileloc = "mypath";
string[] lines = System.IO.File.ReadAllLines(fileloc);
foreach (string line in lines)
{
string[] columns = line.Split(',');
foreach (string column in columns)
{
if (column == textBox5.Text)
{
textBox10.Text = column;
}
}
}
}
This is where I am at right now, with the Powrshell script it identifies the columns in my csv but in C# it doesn't.
below is my spreadsheet and the column headers. I have also added a gif of the Powershell darts gui and my C# gui to show where I am trying to get the finishes to display.
Below is how my Powershell gui Works
as you can see my C# gui is pretty much the same.
Related
I have an app that communicates via BLE to an array of Arduino temperature sensors. I get the data and I normally display it as a table, however I've been playing around in trying to get a line-chart done but It seems I can't get "multiple" lines going. There is a Probearray that has 50 values, so I expect to have 50-lines (albeit most of them should be at the same "temperature" so I should see them overlap, however I have 2 values that the sensor isnt connected so they show really off values, but instead of showing as different lines, they show as part of the same series).
Here's the button code to "open" the graphing window:
private void graphButton_Click(object sender, EventArgs e)
{
graphView.Show();
isGraphing = true;
if (graphView.DialogResult == DialogResult.OK)
{
isGraphing = false;
}
}
Here's the code that is called out every time I get a new "reading" from the Bluetooth device, the reading triggers the "update" of every textbox in the control panel so basically they have the "latest" values:
private void passGraphData()
{
foreach (Control c in sensorTempPanel.Controls)
{
for (int i = 0; i < probeArray.Length; i++)
{
if (c.Name != "" && c.Name.Length > 2)
{
if (probeArray[i].Name == c.Name.Substring(c.Name.Length - 2))
{
this.Invoke((MethodInvoker)delegate { graphView.addGraphData(c.Name.Substring(c.Name.Length - 2), DateTime.Now, Convert.ToSingle(c.Text)); });
}
}
}
}
}
This is the code that's on the graph-view window that I believe should generate its own series per-data value (so if there are 50, each with an individual name there should be 50 series total).
internal void addGraphData(string series, DateTime xPoint, float yPoint)
{
//Every time you parse a new value for each "selected" point you add it individually by sending the series (ProbeLocation), the DateTime and Temp from the TempReadings.
if (lineChart.Series.IndexOf(series) == -1)
{
lineChart.Series.Add(series); //If it doesnt exist, create it.
//lineChart.Series[series]. <- CONFIG STUFF?
}
this.Invoke((MethodInvoker)delegate
{
lineChart.Invalidate();
xValues.Add(xPoint);
yValues.Add(yPoint);
lineChart.Series[series].ChartType = SeriesChartType.Line;
lineChart.Series[series].Points.DataBindXY(xValues, yValues);
});
}
** GOAL DESCRIPTION **
So, my intent is to get 50-lines, I understand (based on the values I see on the tables) I should be getting 2 straight lines with a value of 150 and 1 straight line with a value of -40. However (these are the sensors with some wiring issues) the remaining 47 sensors should be reading somewhere in the 20's (room temperature).
I think my issue is that I am not creating an individual "xValues and yValues" for each series, but I am not sure how to re-use these. . . I understand there's Points.DataBindXY, but is there a reverse of this? (like a Points.GetX and Points.GetY)
However, when I click on the chart button this is my output:
For some reason when I read in clipboard data and write it to a file, read that file in and set it to a list after delineating it with ¢ it loads up my listbox just fine on the first load as in when my form first loads up. However I have the following trigger on a button click, it is for some reason splitting up multiple line sections into separate list items, which is not what I want and not what the same code does when the form first loads. It's a little frustrating as it's writing to the text file and everything the same way.
private void button2_Click_1(object sender, EventArgs e)
{
// until next comment this is the same as what I have run at the start of the
// program, it loads up multiple lines into one list item as it should
string checkForDupe = File.ReadAllText(#"C:\temp\testfile.txt");
string checkResponses = File.ReadAllText(#"C:\temp\testfile2.txt");
if (Clipboard.ContainsText() && !checkForDupe.Contains(Clipboard.GetText()))
{
if (!checkResponses.Contains(Clipboard.GetText()))
{
var text = "\n" + Clipboard.GetText() + "¢";
File.AppendAllText(#"C:\temp\testfile.txt", text);
}
}
//The following has no affect on the issue stated in my question I have tried with out it.
string[] responseTags2 = File.ReadAllLines(#"C:\temp\testfile.txt");
List<string> _responseTags2 = new List<string>(responseTags2);
var count = _responseTags2.Count;
// Perform a reverse tracking.
for (var i = count - 1; i > -1; i--)
{
if (_responseTags2[i] == string.Empty) _responseTags2.RemoveAt(i);
}
// Keep only the unique list items.
_responseTags2 = _responseTags2.Distinct().ToList();
listBox1.BeginUpdate();
listBox1.DataSource = _responseTags2;
listBox1.EndUpdate();
}
input example:
"This is multiple lines in
a text file that is for testing
this application"
right output example (what I get when the same code is running at the start of the program before the form is loaded):
"This is multiple lines in
a text file that is for testing
this application" ,
"This is ANOTHER multiple lines in
a text file that is for testing
this application" ,
"This is a single line"
WRONG output (what I get when I run off the button click that eventual updates the UI):
"This is multiple lines in",
"a text file that is for testing",
"this application"
You are getting multiple lines in your listbox because you are not breaking the text by ¢ but just reading them into lines. This is your code:
string[] responseTags2 = File.ReadAllLines(#"C:\temp\testfile.txt");
Do this instead. Read all the text:
var contents = File.ReadAllText(#"C:\temp\testfile.txt");
Now split them using the character ¢:
var lines = s.Split('¢');
Here is the final linq to remove any empties and return distinct items:
var lines = s.Split('¢')
.Where(item => item != string.Empty)
.Distinct()
.ToList();
Then set lines to be the datasource:
listBox1.BeginUpdate();
listBox1.DataSource = lines;
listBox1.EndUpdate();
This code works fine for me, but I think it's basically what you're doing, only slightly cleaned up (and I didn't use the second file since you're not using it in the example).
My suggestion would be to create a single method that does this operation, and then call that method from wherever you need it. This way you will ensure that you're doing the exact same thing in both (all) places.
UPDATE
I updated the method to save the clipboard text as-is, plus adding a ¢ character to the end, when saving to the file. Then, when reading the file the second time, first join all the lines with a space character, then split on the ¢ character, and use that list for your data source.
private const string DefaultSaveFile = #"C:\temp\testfile.txt";
private void CopyUniqueClipboardTextToFile(string filePath = null,
bool updateListbox = true)
{
// Use global default file if nothing was passed
if (filePath == null) filePath = DefaultSaveFile;
// Ensure our files exist
if (!File.Exists(filePath)) File.CreateText(filePath).Close();
string fileContents = File.ReadAllText(filePath);
string clipboardText = Clipboard.GetText();
// Update the file with any new clipboard text
if (Clipboard.ContainsText() && !fileContents.Contains(clipboardText))
{
// Save the lines to our file, with a '¢' character at the end
File.AppendAllText(filePath, $"{Environment.NewLine}{clipboardText}¢");
}
// Re-read the new file into a single string
string entireFileAsOneLine = string.Join(" ",
File.ReadAllLines(filePath).Distinct().ToList());
// Now split that string on the '¢' character
string[] listItems = entireFileAsOneLine.Split('¢');
// Update listbox if necessary
if (updateListbox)
{
listBox1.BeginUpdate();
listBox1.DataSource = listItems;
listBox1.EndUpdate();
}
}
private void button2_Click(object sender, EventArgs e)
{
CopyUniqueClipboardTextToFile();
}
What I ended up doing is the following;
string responseTags2 = checkForDupe.Replace('\n', '╜');
I replaced new lines with a rarely used character, then split by ¢ to fill the list.
To replace the special character so that it would be formatted correctly again I just replaced it when setting the clipboard text with the \n again.
So i am attempting to teach myself C#, I have a program that I originally wrote in batch and am attempting to recreate in C# using WPF. I have a button that allows a user to set a directory, that directory selected is then displayed in a text box above a listbox which adds every subfolder, only first level, to the listbox. Now all this works fine but it writes out the entire directory path in the listbox. I have been trying to figure out how to strip the leading directory path off the list box entries for over an hour to no avail. Here is what I have so far:
private void btn_SetDirectory_Click(object sender, RoutedEventArgs e)
{
//Create a folder browser dialog and set the selected path to "steamPath"
var steamPath = new FolderBrowserDialog();
DialogResult result = steamPath.ShowDialog();
//Update the text box to reflect the selected folder path
txt_SteamDirectory.Text = steamPath.SelectedPath;
//Clear and update the list box after choosing a folder
lb_FromFolder.Items.Clear();
string folderName = steamPath.SelectedPath;
foreach (string f in Directory.GetDirectories(folderName))
{
lb_FromFolder.Items.Add(f);
}
}
Now I tried changing the last line to this, and it did not work it just crashed the program:
foreach (string f in Directory.GetDirectories(folderName))
{
lb_FromFolder.Items.Add(f.Substring(f.LastIndexOf("'\'")));
}
I am fairly certain that the LastIndexOf route is probably the right one but I am at a dead end. I apologize if this is a dumb question but this is my first attempt at using C#. Thanks in advance.
This can solve your issue
string folderName = steamPath.SelectedPath;
foreach (string f in Directory.GetDirectories(folderName))
{
// string[] strArr = f.Split('\\');
lb_FromFolder.Items.Add(f.Split('\\')[f.Split('\\').Length-1]);
}
You can use this code:
string folderName = steamPath.SelectedPath;
foreach (string f in Directory.GetDirectories(folderName))
{
lb_FromFolder.Items.Add(f.Remove(0,folderName.Length));
}
I'm building a contact manager program and I have a button that when pressed, updates a listBox of names. Unfortunately, I'm expecting my user to not always be putting the names in before closing the program. I have decided to make new contacts in the list appear as random numbers before a name is entered, so some of my items will be numbers and some will be names. I can't seem to get the names to show up, though. I've been storing the names as strings inside of text files contained inside folders of unique random numbers. What I want is to be able to load all the folder names into the list, then check to see if a name is associated with the item, and if it is, replace the number with the respective name. The following code is as far as I have gotten before I got stumped.
private void button5_Click(object sender, EventArgs e)
{
//populate the list of people
listBox1.Items.Clear();
string[] dirs = Directory.GetDirectories(#"C:\PersonalManager\");
foreach (string dir in dirs)
{
//replace numbered items with names
for (int i = 0; i < listBox1.Items.Count; i++)
{
String Text = Convert.ToString(listBox1.Items[i]);
Text = Text.Replace(File.ReadAllText(#"C:\PersonalManager\"+listBox1.Items[i]+#"\first.txt")); //first.txt is the file containing the name
listBox1.Items[i] = Text;
}
listBox1.Items.Add(Path.GetFileName(dir));
}
}
I'm also pretty sure there is an overload bug in there somewhere, as Visual Studio refuses to compile it. Maybe I should go about this in a different way? What would any of you suggest? I have searched all through Google, and Bing but have yet to figure out what I'm doing wrong. Sorry if my code is a mess, it's my first time.
P.S. I'm a beginner, so I can't wrap my head around too much code without comments every now and then.
I'm pretty sure that this line is breaking your code:
Text = Text.Replace(File.ReadAllText(#"C:\PersonalManager\"+listBox1.Items[i]+#"\first.txt"));
The string.Replace does not have a overload with just one parameter. It has always two.
Just to give you a starting point:
private void button5_Click(object sender, EventArgs e)
{
//populate the list of people
listBox1.Items.Clear();
string[] dirs = Directory.GetDirectories(#"C:\PersonalManager\");
foreach (string dir in dirs)
{
var filePathToRead = Path.Combine(dir, "first.txt");
var allTextOfTheFile = File.ReadAllText(filePathToRead);
// now you can work with the content of the file
listBox1.Items.Add(Path.GetFileName(dir));
}
}
I'm studying C# and creating this program to learn a bit more.
My program catchs the information that you have input and save it into a text file. In this part, is alright, but I'm having issues on load the file and show the information inside it.
Example, in the program I have the text boxes for user input his family information:
Dad text box:
Mom text box:
Brother text box:
The text box input is something like:
Dad text box: MyDad
Mom text box: MyMom
Brother text box: MyBrother
When the creation process of file starts, I have in the file the output that I want:
MyDad
MyMom
MyBrother
Okay, now I need to load these informations from the file and write it in another labels, like:
Your Dad is: according to example, I want "MyDad" shown here
Your Mother is: according to example, I want "MyMother" shown here
Your Brother is: according to example, I want "MyBrother" shown here
In the click event of the button to show the informations of the file I have this to check if the file was created and, if was, read it:
string path = #"C:\Users\Hypister\Desktop\Family.txt";
if (File.Exists(path))
{
using (StreamReader sr = File.OpenText(path))
{
//Here I need the function to get the lines and show it in respective labels.
}
}
else
{
MessageBox.Show("The file doesn't exists. Data cannot be loaded.");
}
But I cannot get the line for Dad, Mother and Brother from the file to show.
I hope someone can answer this and help me to gain more knowledge.
Thanks all in advance!
I coded an example for you a good C# file reference is http://msdn.microsoft.com/en-us/library/ezwyzy7b.aspx for future reference.
there 3 textboxes 3 labels and a button all default names
here is the source code hope it helps :)
private void button1_Click(object sender, EventArgs e)
{
List<string> family = new List<string>();
family.Add(textBox1.Text);
family.Add(textBox2.Text);
family.Add(textBox3.Text);
family.ToArray();
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\OEM\Desktop\stackoverflow\test.txt"))
{
foreach (string line in family)
{
file.WriteLine(line);
}
}
string[] familyout = System.IO.File.ReadAllLines(#"C:\Users\OEM\Desktop\stackoverflow\test.txt");
/* this works just fine unless you have alot of labels, the code not commented out below this works better
label1.Text = familyout[0];
label2.Text = familyout[1];
label3.Text = familyout[2];
*/
int i = 0;
foreach (Control lbl in this.Controls)
{
if (lbl is Label)
{
lbl.Text = familyout[i];
i++;
}
}
}