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;
}
}
Related
I am creating an app that i need to copy some png files.
I already have searching with many keywords, finding many solutions and none of them worked, so i decided to ask here.
There is the code,it uses a windows forms and "this" refers to this window
private void button2_Click(object sender, EventArgs e)
{
//yes i commented them to solve why the file was not copying
//try
{
FileInfo x = new FileInfo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\some_location");
x.CopyTo(textBox1.Text);
}
//catch
{ }
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Title = "Select Image To Load";
openDialog.Filter = "Text Files (*.png)|*.png" + "|" + "All Files (*.*)|*.*";
if (openDialog.ShowDialog() == DialogResult.OK)
{
string PathData = openDialog.FileName;
textBox1.Text = PathData;
}
}
I have gotten several different errors, but most common there is:
System.UnauthorizedAccessException
It looks a bit weird to me that you're using an OpenFileDialog to select a destination. I'd assume you'd want to either do it the other way around:
private void button2_Click(object sender, EventArgs e)
{
//yes i commented them to solve why the file was not copying
//try
{
FileInfo x = new FileInfo(textBox1.Text);
x.CopyTo(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\some_location");
}
//catch
{ }
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Title = "Select Image To Load";
openDialog.Filter = "Text Files (*.png)|*.png" + "|" + "All Files (*.*)|*.*";
if (openDialog.ShowDialog() == DialogResult.OK)
{
string PathData = openDialog.FileName;
textBox1.Text = PathData;
}
}
or use SaveFileDialog instead.
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.
I've a gui and I get temperature data from a Uc. I can see the data in the rich text box and save to a text file. But I cannot understand how to sort the saved data in the column format. Right now it is a long row of data. Please advice.
Would it be advisable to replace the rich text box to a normal text box?
I've a button to save data to the text file (button3_Click);
using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
namespace Serial_receive
{
public partial class Form1 : Form
{
// All members variables should be placed here
// make it more readable, hopefully!
string t;
SerialPort sp;
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
// User can already search for ports when the constructor of the FORM1 is calling
// And let the user search ports again with a click
// Searching for ports function
SearchPorts();
}
//search button
private void button1_Click(object sender, EventArgs e)
{
comboBox1.Items.Clear();
SearchPorts();
}
void SearchPorts()
{
string[] ports = SerialPort.GetPortNames();
foreach (string port in ports)
{
comboBox1.Items.Add(port);
}
}
private void button2_Click(object sender, EventArgs e)
{
// Catch exception if it will be thrown so the user will see it in a message box
OpenCloseSerial();
}
void OpenCloseSerial()
{
try
{
if (sp == null || sp.IsOpen == false)
{
t = comboBox1.Text.ToString();
sErial(t);
button2.Text = "Close Serial port"; // button text
}
else
{
sp.Close();
button2.Text = "Connect and wait for inputs"; // button text
}
}
catch (Exception err) // catching error message
{
MessageBox.Show(err.Message); // displaying error message
}
}
void sErial(string Port_name)
{
try
{
sp = new SerialPort(Port_name, 115200, Parity.None, 8, StopBits.One); // serial port parameters
sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
sp.Open();
}
catch (Exception err)
{
throw (new SystemException(err.Message));
}
}
//
private void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
{
// This below line is not need , sp is global (belongs to the class!!)
//SerialPort sp = (SerialPort)sender;
if (e.EventType == SerialData.Chars)
{
if (sp.IsOpen)
{
string w = sp.ReadExisting();
if (w != String.Empty)
{
Invoke(new Action(() => richTextBox1.AppendText(w)));
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (sp == null || sp.IsOpen == false)
{
OpenCloseSerial();
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "Serial Channel to FRDM-KW40Z";
}
private void button3_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.InitialDirectory = #"C:\Users\varman\Documents\";
saveFileDialog1.Title = "Save text Files";
saveFileDialog1.CheckFileExists = true;
saveFileDialog1.CheckPathExists = true;
saveFileDialog1.DefaultExt = "txt";
saveFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string temperature = "Temperature";
string sorted = richTextBox1.Text.Replace(temperature, Environment.NewLine + temperature);
sorted = sorted.Substring(sorted.IndexOf(temperature));
File.WriteAllText(saveFileDialog1.FileName, sorted);
Text += "\r\n";
richTextBox1.Text = saveFileDialog1.FileName;
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
richTextBox1.ScrollBars = ScrollBars.Both;
}
}
}
I assume you want to sort it only in the output file because you didn't share the code that change richTextBox1.Text.
So you can add a new line for each temperature before writing to the file:
private void button3_Click(object sender, EventArgs e)
{
...
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string temperature = "Temperature";
string sorted = richTextBox1.Text.Replace(temperature, Environment.NewLine + temperature);
File.WriteAllText(saveFileDialog1.FileName, sorted);
Text += "\r\n";
richTextBox1.Text = saveFileDialog1.FileName;
}
}
Add this line of code before File.WriteAllText if you want to write the text that starts with "Temperature" (this way you remove the "?????" at the beginning):
sorted = sorted.Substring(sorted.IndexOf(temperature));
EDIT:
Following your last edit - you added the code that updates the RichTextBox. So you can do the sorting by column only in DataReceivedHandler. See below:
private void DataReceivedHandler(object sender,SerialDataReceivedEventArgs e)
{
if (e.EventType != SerialData.Chars || !sp.IsOpen)
{
return;
}
string w = sp.ReadExisting();
if (w != String.Empty)
{
string temperature = "Temperature";
string sorted = w.Replace(temperature, Environment.NewLine + temperature);
Invoke(new Action(() => richTextBox1.AppendText(sorted)));
}
}
Basically what you need to understand is that File.WriteAllText(fileName, input) is where you write input into the file, so you can manipulate input as you wish before that line. If you wish to alter the text before it's dispalyed in the RichTextBox then you need to see where you execute something like richTextBox1.AppendText(input) or richTextBox1.Text = input and do all the changes you want on input before that line.
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
I have a question about the opfiledialog function within c#. When i dont select a file with openfiledialog it put's a text automaticly in my textbox. That text will be "filedialog1". What can i do to fix this.
using System;
using System.Windows.Forms;
using System.IO;
namespace Flashloader
{
public partial class NewApplication : Form
{
private toepassinginifile _toepassinginifile;
private controllerinifile _controllerinifile;
//private controllerinifile _controlIniFile;
public NewApplication(toepassinginifile iniFile)
{
_controllerinifile = new controllerinifile();
_toepassinginifile = iniFile;
InitializeComponent();
controllerComboBox.DataSource = _controllerinifile.Controllers;
}
public bool Run()
{
var result = ShowDialog();
return result == System.Windows.Forms.DialogResult.OK;
}
private void button4_Click(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "Srec Files (.a20; .a21; .a26; .a44)|*.a20; *.a21; *.a26; *.a44|All files (*.*)|*.*";
openFileDialog1.Title = ("Choose a file");
openFileDialog1.InitialDirectory = Path.Combine(Directory.GetCurrentDirectory());
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
fileBox.Text = (System.IO.Path.GetFileName(openFileDialog1.FileName));
}
}
private void button3_Click(object sender, EventArgs e)
{
Toepassing toepassing = new Toepassing();
toepassing.Name = nameBox.Text;
toepassing.Controller = (Flashloader.Controller)controllerComboBox.SelectedItem;
toepassing.TabTip = descBox.Text;
toepassing.Lastfile = openFileDialog1.FileName;
fileBox.Text = openFileDialog1.FileName;
if (nameBox.Text == "")
MessageBox.Show("You haven't assigned a Name");
else if (controllerComboBox.Text == "")
MessageBox.Show("You haven't assigned a Controller");
else if (descBox.Text == "")
MessageBox.Show("You haven't assigned a Desciption");
else if (fileBox.Text == "")
MessageBox.Show("You haven't assigned a Applicationfile");
_toepassinginifile.ToePassingen.Add(toepassing);
_toepassinginifile.Save(toepassing);
MessageBox.Show("Save Succesfull");
DialogResult = DialogResult.OK;
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
var newcontroller = new Newcontroller(_controllerinifile);
newcontroller.ShowDialog();
controllerComboBox.DataSource = null;
controllerComboBox.DataSource = _controllerinifile.Controllers;
}
}
}
Thanks all for the help
private void button3_Click(object sender, EventArgs e)
{
toepassing.Lastfile = openFileDialog1.FileName;// Dont do this
fileBox.Text = openFileDialog1.FileName; //or this
Its unclear to me why you are holding onto an Open file dialog I would personally do the following
using(OpenFileDialog ofd = new OpenFileDialog())
{
if(ofd.ShowDialog() == DialogResult.OK)
{
classStringVariable = ofd.FileName;
fileBox.Text = ofd.FileName;
}
}
Then in button 3
toepassing.LastFile = classStringVariable ;
fileBox.Text = classStringVariable ;
When you use the Form Designer to add an OpenFileDialog control on you form, the designer assigns at the property FileName the value openFileDialog1.
I suppose you have set something as the initial value for the property FileName. Then in button_click3 you have no mean to check for the DialogResult and thus you get inconditionally this default back.
Fix it removing this default from the designer FileName property
Just add openFileDialog1.FileName= ""; before you show the dialog.
openFileDialog1.Filter = "Srec Files (.a20; .a21; .a26; .a44)|*.a20; *.a21; *.a26; *.a44|All files (*.*)|*.*";
openFileDialog1.Title = ("Choose a file");
openFileDialog1.InitialDirectory = Path.Combine(Directory.GetCurrentDirectory());
openFileDialog1.RestoreDirectory = true;
openFileDialog1.FileName = "";
if (openFileDialog1.ShowDialog() == DialogResult.OK && openFileDialog1.FileName != "")
{
fileBox.Text = (System.IO.Path.GetFileName(openFileDialog1.FileName));
}
In your button3_Click event you're checking for an empty string file name anyways, so they would get the correct error message and they wouldn't have some weird arbitrary default name show up when they open the dialog.