I am creating an application would take textfile paths from a textfile, and then load them into a listbox, which when clicked on in listbox, the textfile content will spawn in a script editor widget called textEditorControl1.
The thing is. When I delete a thing from the listbox which hosts the textfile names, AND THEN, click on another item in listbox; it gives me an error:
An unhandled exception of type 'System.ArgumentOutOfRangeException'
occurred in mscorlib.dll
Additional information: Index was out of range. Must be non-negative
and less than the size of the collection.
on string fullFileName2 = selectedScripts[listBox3.SelectedIndex];
List<String> fullFileName;
List<String> fullFileName2;
List<string> selectedScripts = new List<string>();
public void listBox3_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox3.SelectedIndex >= 0)
{
string fullFileName2 = selectedScripts[listBox3.SelectedIndex];
textBox3.Text = fullFileName2;
string File1 = fullFileName2;
string text = System.IO.File.ReadAllText(File1);
textEditorControl1.Text = text;
textEditorControl1.Refresh();
}
else
{
}
private void materialFlatButton10_Click(object sender, EventArgs e)
{
OpenFileDialog OpenFileDialog1 = new OpenFileDialog();
OpenFileDialog1.Multiselect = true;
OpenFileDialog1.Filter = "Text Files|*.txt|All Files|*.*|Lua Files|*.lua";
OpenFileDialog1.Title = "Select a Text/Lua File";
if (OpenFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
fullFileName2 = new List<String>(OpenFileDialog1.FileNames);
foreach (string s in OpenFileDialog1.FileNames)
{
listBox3.Items.Add(Path.GetFileName(s));
selectedScripts.Add(s);
}
}
}
private void deleteFromListToolStripMenuItem_Click(object sender, EventArgs e)
{
label4.Text = " ";
textBox3.Text = "";
IDocument document = textEditorControl1.Document;
document.Remove(0, document.TextLength);
textEditorControl1.Refresh();
selectedScripts.Clear();
for (int i = listBox3.SelectedIndices.Count - 1; i >= 0; i--)
{
listBox3.Items.RemoveAt(listBox3.SelectedIndices[i]);
}
}
You're clearing SelectedScripts, and then when you click on something, you're trying to access an item in SelectedScripts at index listBox3.SelectedIndex, but at this point SelectedScripts is empty.
I think your delete method should be this:
private void deleteFromListToolStripMenuItem_Click(object sender, EventArgs e)
{
label4.Text = " ";
textBox3.Text = "";
IDocument document = textEditorControl1.Document;
document.Remove(0, document.TextLength);
textEditorControl1.Refresh();
for (int i = listBox3.SelectedIndices.Count - 1; i >= 0; i--)
{
selectedScripts.RemoveAt(listBox3.SelectedIndices[i]);
listBox3.Items.RemoveAt(listBox3.SelectedIndices[i]);
}
}
Note that the UI ListBox control can take classes, so you could encapsulate all of your data into one class object which you add to the list.
Related
Today when I type something any text in textBox1 and then click the start button it will search inside files for the text i typed in textBox1.
Now I want to add something somehow that if the user type in the textBox1 for example: hello,hi it will search for hello and also for hi in the files. Not as one string/text but two separated. If I type: hello,hi,world now it will search in same time same files also for hello hi and world.
The textchanged event
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text != "" && textBox3.Text != "" && Directory.Exists(textBox3.Text))
{
startButton.Enabled = true;
Properties.Settings.Default["Setting2"] = textBox1.Text;
Properties.Settings.Default.Save();
}
else
{
startButton.Enabled = false;
}
}
The start button click event
private void startButton_Click(object sender, EventArgs e)
{
label21.Visible = true;
startButton.Enabled = false;
stopButton.Enabled = true;
pauseresumeButton.Enabled = true;
timer1.Start();
if (!backgroundWorker1.IsBusy)
{
SetWorkerMode(true);
backgroundWorker1.RunWorkerAsync();
}
}
Dowork event
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
_stopwatch.Restart();
DirSearch(textBox3.Text, textBox2.Text, textBox1.Text, worker, e);
_stopwatch.Stop();
}
The DirSearch method where I search for the text in files.
void DirSearch(string rootDirectory, string filesExtension, string textToSearch, BackgroundWorker worker, DoWorkEventArgs e)
{
List<string> filePathList = new List<string>();
List<string> restrictedFiles = new List<string>();
int overallfiles = 0;
int numberoffiles = 0;
int numberofdirs = 0;
try
{
filePathList = SearchAccessibleFilesNoDistinct(rootDirectory, null).ToList();
}
catch (Exception err)
{
string ad = err.ToString();
}
foreach (string file in filePathList)
{
try
{
_busy.WaitOne();
if (worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
List<MyProgress> prog = new List<MyProgress>();
int var = File.ReadAllText(file).Contains(textToSearch) ? 1 : 0;
overallfiles++;
if (var == 1)
{
numberoffiles++;
prog.Add(new MyProgress { Report1 = file, Report2 = numberoffiles.ToString() });
backgroundWorker1.ReportProgress(0, prog);
}
numberofdirs++;
label1.Invoke((MethodInvoker)delegate
{
label1.Text = numberofdirs.ToString();
label1.Visible = true;
});
}
catch (Exception)
{
restrictedFiles.Add(file);
continue;
}
}
}
In DirSearch the variable textToSearch contains the text I typed in textBox1.
If I typed in textBox1 only HI so like it is now it will search in each file for the existing of HI.
But if I type HI,HELLO,WORLD
Now I want it to search for existing in each file of HI HELLO WORLD not as one text string but each word on it's own existing.
If I type Hi HELLO WORLD then it will search it as one string/text but once the user put , between it should search each word/text.
You can split the input in the textbox based on space, comma's or any other separator and then pass these as individual inputs to your search method, hope this helps
So, I set up a file browser, fully working.
But now I want to take the end location where you went and put that location into a TextBox. Which can still be typed in by the user for if they want to manually type the file location.
private void button1_Click(object sender, EventArgs e)
{
int size = -1;
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
size = text.Length;
}
catch (IOException) { }
}
Console.WriteLine(size);
Console.WriteLine(result);
}
You can get the full path
textBox1.Text = file;
and the last folder name
string lastFolderName = Path.GetFileName(Path.GetDirectoryName(file));
textBox1.Text = lastFolderName;
in your code you can use like below, if you want to use the location from another scope then make file variable global
string file = "";
private void button1_Click(object sender, EventArgs e)
{
int size = -1;
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
size = text.Length;
textBox1.Text = file; // for full location
textBox2.Text = Path.GetFileName(Path.GetDirectoryName(file)); // for last folder name
}
catch (IOException)
{
}
}
}
and then
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Text = file;
}
I have an app that reads a directory, gets a list of the files (segy) and populates a listbox on the left side of the app with the filenames. Upon clicking an item in the listox I'd like the rich text box on the right to display the content of the file.
I have the app working if I use the openfiledialog to select one of the files in the directory, I'm having issues trying to get the stream reader to read the selected file I've clicked.
The working simple openfiledialog code below.
openFileDialog1.Filter = "All Files|*.*";
openFileDialog1.Title = "Open SEG-Y Files";
DialogResult result = openFileDialog1.ShowDialog();
StreamReader readFile = new StreamReader(openFileDialog1.FileName, ebcdic);
readFile.BaseStream.Seek(0, SeekOrigin.Begin);
readFile.Read(data, 0, 3200);
string stringData = "";
for (int i = 0; i < data.Length; i++)
{
if ((i % 80) == 0 && stringData != "")
stringData += Environment.NewLine;
stringData += data[i].ToString();
}
rtbHeader.Text = stringData;
rtb.AppendText(value);
rtb.AppendText(System.Environment.NewLine);
My code
private void txtUpdate(string value)
{
lstFiles.Items.Add(value + Environment.NewLine);
lstFiles.TopIndex = lstFiles.Items.Count - 1;
lstFiles.Update();
}
private void btnFolder_Click(object sender, EventArgs e)
{
txtPath.Text = "";
lstFiles.Items.Clear();
rtbHeader.Clear();
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
txtPath.Text = folderBrowserDialog1.SelectedPath;
}
}
private void btnFiles_Click(object sender, EventArgs e)
{
lstFiles.Items.Clear();
string path = txtPath.Text;
List<string> files = new List<string>(Directory.EnumerateFiles(txtPath.Text, "*.sgy", SearchOption.AllDirectories).Select(Path.GetFileName).OrderBy(x => x));
if (files == null || files.All(x => string.IsNullOrWhiteSpace(x)))
{
MessageBox.Show("There are no files with extension" + " sgy", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
foreach (string file in files)
{
this.Invoke(new Action(() => txtUpdate(file)));
}
}
private void lstFiles_MouseClick(object sender, MouseEventArgs e)
{
rtbHeader.Clear();
String item = (Convert.ToString(lstFiles.SelectedItem));
//MessageBox.Show(item);
StreamReader readFile = new StreamReader(item, ebcdic);
readFile.BaseStream.Seek(0, SeekOrigin.Begin);
readFile.Read(data, 0, 3200);
string stringData = "";
for (int i = 0; i < data.Length; i++)
{
if ((i % 80) == 0 && stringData != "")
stringData += Environment.NewLine;
stringData += data[i].ToString();
}
rtbHeader.Text = stringData;
}
}
Im getting an Illegal characters in path exception on this bit.
StreamReader readFile = new StreamReader(item, ebcdic);
Thanks
The code example really should be simpler. Much simpler. And the problem description more specific. Much more specific. See https://stackoverflow.com/help/mcve and https://stackoverflow.com/help/how-to-ask
That said, I believe that if you change this statement in the txtUpdate() method:
lstFiles.Items.Add(value + Environment.NewLine);
to this:
lstFiles.Items.Add(value);
It will work. The exception is most likely caused by the fact that you have newline characters in your strings. Not only does that make the filename not the one you want, it's not a valid character in Windows paths.
Also note that the items in the ListBox you've added are already strings. You don't need to call Convert.ToString() on them. You can just cast them back to a string:
String item = (string)lstFiles.SelectedItem;
How can I limit the number of files to be uploaded using the multi-select openfiledialog in c#?
Here's my code:
private void btn_upload_Click(object sender, EventArgs e)
{
OpenFileDialog op1 = new OpenFileDialog();
op1.Multiselect = true;
op1.ShowDialog();
op1.Filter = "allfiles|*.xls";
textBox1.Text = op1.FileName;
int count = 0;
string[] FName;
foreach (string s in op1.FileNames)
{
FName = s.Split('\\');
File.Copy(s, "C:\\file\\" + FName[FName.Length - 1]);
count++;
}
MessageBox.Show(Convert.ToString(count) + " File(s) copied");
}
It will upload as how much the user wants to. But I want to limit it by 5 files only.
You can't do that directly but you can check the selected files count and display a message to user:
if(op1.FileNames.Length > 5)
{
MessageBox.Show("your message");
return;
}
Or you can take the first five file from selected files:
foreach (string s in op1.FileNames.Take(5))
{
...
}
I just tested and this works:
private void btn_upload_Click(object sender, EventArgs e)
{
OpenFileDialog op1 = new OpenFileDialog();
op1.Multiselect = true;
op1.FileOk += openFileDialog1_FileOk; // Event handler
op1.ShowDialog();
// etc
}
void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
OpenFileDialog dlg = sender as OpenFileDialog;
if (5 < dlg.FileNames.Length)
{
MessageBox.Show("Too Many Files");
e.Cancel = true;
}
}
I have made a method so that when you click on Browse From File the openDialogBox appear. But it does not . What is wrong ?
This is the method that I made to Open the OpenFileDialog:
public void Lista()
{
string[] col2 = new string[dataGridView1.Rows.Count];
for (int i = 0; i < dataGridView1.Rows.Count; i++)
if (col2[i] == "Browse From File...")
{
DialogResult result2 = openFileDialog2.ShowDialog();
if (result2 == DialogResult.OK)
{
// filename = openFileDialog1.FileName;
}
}
}
This is the method where I call the method Lista.
private void button1_Click(object sender, EventArgs e)
{
// opens window **BROWSE**
openFileDialog1.Title = "Choose File CSV ";
string filename = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
filename = openFileDialog1.FileName;
textBox1.Text = filename;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(textBox1.Text);
stringforData = file.ReadLine();
while ((line = file.ReadLine()) != null)
{
//read inside the table
fileList.Add(line.Split(';'));
}
file.Close();
this.ToDataGrid();
this.Lista();
}
}
DataGridView by only having one editing control for all the rows. Here's how I handled a similar situation, First try a delegate to the EditControlShowing event
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
OpenFileDialog ofd = new OpenFileDialog();
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.Columns.Add("ID", "Product ID");
DataGridViewComboBoxColumn comboxboxCol = new DataGridViewComboBoxColumn();
comboxboxCol.HeaderText = "Type";
comboxboxCol.Items.Add("Obj1");
comboxboxCol.Items.Add("Obj2");
comboxboxCol.Items.Add("Obj3");
dataGridView1.Columns.Add(comboxboxCol);
dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(Grid_EditingControlShowing);
}
void Grid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox combo = e.Control as ComboBox;
if (combo != null)
{
// the event to handle combo changes
EventHandler comboDelegate = new EventHandler(
(cbSender, args) =>
{
ofd.ShowDialog();
});
// register the event with the editing control
combo.SelectedValueChanged += comboDelegate;
}
}
}
}
Hope this will solve your Issue