C#: how to check and display the content of a folder? - c#

I'm not sure whether this topics has been disscussed before or not, but I'm not sure the exact word to search for it. What method/class should I use?
The program has 3 buttons: 1) for folder browsing, 2) scan for the selected folder content, and 3) open the file. When user browse the selected folder**(1), user click scan button to scan from the first file until the last available files and listed it text box(2)** and from that user can decide whether to open the files or not**(3)**.
Here are what have I done so far (no 1 and 3):
//For browse.
private void browse2()
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
this.txtDest.Text = folderBrowserDialog1.SelectedPath;
}
}
//For opening folder.
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
Process.Start(txtDest.Text);
}
catch
{
MessageBox.Show("Please select one file/folder");
}
}

If you are trying to just open a file you can directly use an Open File Dialog.
If you need to display the contents of a directory you can use the Directory Info Class.

Well my example is a WPF app that adds files/ folders in a directory to a treeview, but you should get the general idea:
Note: Code was written for a training exercise, and therefore only goes 3 levels deep, as a proof of concept kind of thing
private void Window_Loaded(object sender, RoutedEventArgs e)
{
foreach (DriveInfo di in DriveInfo.GetDrives())
{
TreeViewItem drive = new TreeViewItem();
drive.Header = di.Name;
treeView1.Items.Add(drive);
DirectoryInfo folders = new DirectoryInfo(di.Name);
// The depth count means that it only goes 3 levels deep, to make it quick to load
GetFoldersAndFiles(drive, folders, 3);
}
}
private static void GetFoldersAndFiles(TreeViewItem parent, DirectoryInfo folders, int depth)
{
if ((depth > 0)
{
foreach (DirectoryInfo dirI in folders.GetDirectories())
{
TreeViewItem dir = new TreeViewItem();
dir.Header = dirI.Name;
parent.Items.Add(dir);
GetFoldersAndFiles(dir, dirI, depth - 1);
}
foreach (FileInfo fileI in folders.GetFiles())
{
TreeViewItem file = new TreeViewItem();
file.Header = fileI.Name;
parent.Items.Add(file);
}
}
}

Related

drag and drop files from folder c# wpf

I am attempting to have ListView in my WPF application, which accepts drag and drop - both files and directories, but in case of directories it is supposed to get files from them, not them themselves.
My XAML:
<ListView ... AllowDrop="True" Drop="importListView_Drop">
...
</ListView>
My code behind:
private void importListView_Drop(object sender, DragEventArgs e)
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
core.AddIntoImport(files);
}
This now produces outputs including directories and omitting files in them, f.e.
C:/Example/Files/MyFile.mp3
C:/Example/Files/SubDirectory/
...
While I'd like it to actually get all files from SubDirectory and not include SubDirectory itself. I could do this by myself: "is directory? - yes: exclude it and get all files from it instead" but the question is, is there some nicer way included in f.e. event args already?
Just to make myself more clear, following code does the job perfectly in WinForms app. Is there an alternative in WPF?
private void Form1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
InsertImport(files);
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
}
You could use this
var allFiles = files.Where(Directory.Exists)
.SelectMany(dir => Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories))
.ToList();
Just be aware, this is will throw if you have don't have appropriate permissions on the sub directories. in such case you will have to do this more manually, and check-for / ignore errors
Managed to do this in this way in the end btw...:
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
var importList = new List<string>();
foreach (string s in files)
{
if (Directory.Exists(s))
foreach (var f in Directory.GetFiles(s, "*.*", SearchOption.AllDirectories))
importList.Add(f);
else if (File.Exists(s))
importList.Add(s);
}

C# Open selected listview items using foreach

What should be in (???)
I want to open for example 3 selected files in my simple file explorer
private void Open_Click(object sender, System.EventArgs e)
{
foreach (???)
{
string ImageViewName = listView1.SelectedItems[0].Text;
System.Diagnostics.Process.Start(#textBox1.Text.Remove(3, 1) + "/" + ImageViewName);
}
}
in textbox1 is my path to the files
Assuming each File is in a List called Files
foreach (File myFile in Files){
//Do something with myFile
}
The foreach block will iterate through each File in Files. The current selected file, which can be accessed from within the foreach block, is called 'myFile' in this instance.
I am new to stackoverflow so I'm open to advice about my answer too!

Using textbox to gather user's destination path for exporting a CSV in C# Windows application?

I'm looking for an option that allows a user to input their destination folder (Usually copy/Paste) into a text box on a Windows Application, and append the file's name with a specific name. However, I'm stuck as to how to accomplish this.
//Exporting to CSV.
string folderPath = MessageBox.Show(textBox1_TextChanged);
File.WriteAllText(folderPath + "DIR_" + (DateTime.Now.ToShortDateString()) + ".csv", csv);
So it can look like: C:/DIR_9132017.csv, or Documents/DIR_9132017.csv, depending on what the user inputs into the textbox. I have nothing in my textbox code section at the moment, if that also gives a clearer picture about the situation.
Any help will be greatly appreciated. Thank you!
You can either use FolderBrowserDialog or can just copy/paste the path and create the directory.
Using FolderBrowserDialog
Step1 : Create Browse button (so that the user can choose the directory)
Step2 : Create Export button (Place the code to write the file here)
private void browseButton_Click(object sender, EventArgs e)
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
var folderPath = folderBrowserDialog1.SelectedPath;
textBox1.Text = folderPath;
}
}
private void exportToCsvButton_Click(object sender, EventArgs e)
{
var path = textBox1.Text;
var file = Directory.CreateDirectory(path);
var filename = "DIR_" + (DateTime.Now.ToShortDateString()) + ".csv";
File.WriteAllText(Path.Combine(path, "test.csv"), "content");
}
Using Copy/Paste
Step1 : Create Export button (User copy pastes the path. System create the directory and writes the file)
private void exportToCsvButton_Click(object sender, EventArgs e)
{
var path = textBox1.Text;
var file = Directory.CreateDirectory(path);
var filename = "DIR_" + (DateTime.Now.ToShortDateString()) + ".csv";
File.WriteAllText(Path.Combine(path, "test.csv"), "content");
}
You would use a FolderBrowserDialog for that. After adding it to your form, you can use it like this:
public void ChooseFolder()
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
folderPath = folderBrowserDialog1.SelectedPath;
}
}
Source: https://msdn.microsoft.com/en-us/library/aa984305(v=vs.71).aspx
You haven't specified whether it's WinForms or WPF, so I'm using WPF, but is should be the same in WinForms.
To select the folder, you could use FolderBrowseDialog as follows. This code should be placed inside a button or some other similar control's Click event.
if (folderBrowse.ShowDialog() == DialogResult.OK)
{
txtPath.Text = folderBrowse.SelectedPath;
}
txtPath being a TextBox your selected path displayed in. You can substitute it with a simple string variable if you don't want to use a TextBox.
And if you want the user to be able to drag-drop a folder into a TextBox, you can create a TextBox control, and in it's PreviewDragOver and Drop events, you can do the following.
private void txtPath_PreviewDragOver(object sender, DragEventArgs e)
{
e.Handled = true;
}
private void txtPath_Drop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files != null && files.Length != 0)
txtPath.Text = files[0];
}
Using both above in combination user has the ability to either select the folder he/she wants by clicking a button, drag-and-drop a folder into the TextBox, or copy-paste the folder path into the TextBox.

Hide/modify string in listView

I am making a program in which users can modify remote files. I put the selected files (depending on some predefined criteria) in a listView, but I display only the file names, not full filepaths.
The problem I get however, is that when a user would double-click on an item, it should open another window to modify that item.
private void listView1_DoubleClick(object sender, EventArgs e)
{
account = File.ReadAllLines("\\\\myremoteserver\\ftp\\"+listView1.SelectedItems[0].Text+".txt");
Form3 passForm = new Form3();
passForm.ShowDialog();
}
private void Form2_Load(object sender, EventArgs e)
{
string[] files = Directory.GetFiles("\\\\myremotserver\\ftp\\","*.txt", System.IO.SearchOption.AllDirectories);
foreach (string s in files)
{
listView1.Items.Add(Path.GetFileNameWithoutExtension(s));
}
}
The problem is, that the files are all in different subfolders, so if I leave the code as is, it will not display the correct content of the file. For example, the file is called test1.txt, it is placed in myremoteserver\ftp\testfolder\test1.txt, but with my program, it will try to find the file in myremoteserver\ftp\test1.txt.
What I am asking is, if it is possible to modify the listView in such a way, that the full file path is always saved, but only the file names are displayed? I do not want the user to see the complete file path of the files, just the file names.
Use the Tag property of the ListViewItem
So to create items...
foreach (string s in files)
{
ListViewItem lvi = new ListViewItem(Path.GetFileNameWithoutExtension(s));
lvi.Tag = s;
listView1.Items.Add(lvi);
}
Then in event handler...
account = File.ReadAllLines("\\\\myremoteserver\\ftp\\"+listView1.SelectedItems[0].Tag +".txt);

Get File Name from a Path in Listbox Item

I want to reduce the length of the path and display only the file name.
For example, suppose the path is c:\\program files\...\123.jpg I want to display only 123.jpg.
Here is the code I have been working with thus far. Can anyone suggest modifications?
private void button1_Click(object sender, EventArgs e)
{
panel3.Controls.Clear();
var ofd = new OpenFileDialog();
ofd.Multiselect = true;
ofd.Filter = "DICOM Files (*.dcm;*.dic)|*.dcm;*.dic|All Files (*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.Cancel)
return;
foreach (string s in ofd.FileNames)
{
listBox1.Items.Add(s);
}
}
There is a class named Path in System.IO namespace.
Between its numerous static methods you could find
Path.GetFilename(string);
Using it in your Add loop you could set only the filenames
listBox1.Items.Add(Path.GetFileName(s));
However, I suggest to save the folder name somewhere, because if you need to process these files you need it. And, guess what, Path has a method also to extract a path from a full filename
if(filenames.Length > 0)
string workingPath = Path.GetDirectoryName(filenames[0]);
EDIT
From your comments below it seems that you call this button_click more than one time and every time you select a different folder. In this case, stripping the path part from the selected filenames leaves your listbox filled with files that you can't retrieve because you don't know the path part (stripped away). If you need to retrieve the files selected to execute some kind of process, then you need to store somewhere the full path of these files and be able to retrive them.
You can achieve this result storing the files selected in a List<string> instance.
Declare at the global level a variable to store these full filenames
(Add using System.Collection.Generic;)
List<string> selectedFiles = new List<string>();
Now inside the button click add the full filename to the List<string> and the stripped file to the ListBox items, in the same order
private void button1_Click(object sender, EventArgs e)
{
panel3.Controls.Clear();
var ofd = new OpenFileDialog();
ofd.Multiselect = true;
ofd.Filter = "DICOM Files (*.dcm;*.dic)|*.dcm;*.dic|All Files (*.*)|*.*";
if (ofd.ShowDialog() == DialogResult.Cancel)
return;
foreach (string s in ofd.FileNames)
{
listBox1.Items.Add(Path.GetFileName(s));
selectedFiles.Add(s);
}
}
Now, if you want to retrieve the full path for the selected file in the listbox you could use
private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
if(listBox1.SelectedIndex >= 0)
{
string fullFileName = selectedFiles[listBox1.SelectedIndex];
.... process the filename ....
}
}
Use Path.GetFileName() to return the name
see http://msdn.microsoft.com/en-us/library/system.io.path.getfilename(v=vs.110).aspx

Categories