add items properties - c# winform - c#

I'd like to load the multiple files (like Images, Documents, Pdfs) to the listview and along its properties will be displayed.
This was the code I am working with:
FileInfo FInfo;
DialogResult dr = this.openFD.ShowDialog();
if (dr == System.Windows.Forms.DialogResult.OK)
{
// Read the files
foreach (String file in openFD.FileNames)
{
string fileName = Path.GetFileNameWithoutExtension(file);
ListViewItem item = new ListViewItem(fileName);
item.Tag = file;
listView1.Items.Add(item);
}
}
Please help me.

Here is the way I do for Excel files. You just need to modify it a bit. I am hoping this helps.
private void loadMatchingResponsesReports()
{
listBox2.Items.Clear();
string[] list = getMatchingReports();
foreach (String S in list)
{
FileInfo fileResponse = new FileInfo(S);
string fileResponseNameOnly = fileResponse.Name;
listBox2.Items.Add(fileResponseNameOnly);
GC.Collect();
}
}
public string[] getMatchingReports()
{
string[] returnR = null;
try
{
returnR = Directory.GetFiles(textBox3.Text + #"\", "*.xls");
}
catch
{
MessageBox.Show("Can't get some files from directory " + textBox3.Text);
}
return returnR;
}

Instead of a simple string, you might want to use a custom object to store all properties you want associated with the ListViewItem.
item.Tag = file;
file should be of custom type, a Dictionary<string, string> maybe.

You need to use the FileInfo class. For each file you want to add, construct an instance. It as has all the properties you would want to add to an explorer like interface such as: CreationTime, Extension, Name etc. You get the size (in bytes) from the Length property.
You would add a ListViewSubItem for each attribute, corresponding to the column in your ListView.

Related

Read the contents of a listView, and display missing items in another listView based on the contents of a directory

I have a .NET webform that is displaying files found in a directory in a listView. This is the code for the display:
private void files()
{
try
{
DirectoryInfo dinfo = new DirectoryInfo(label2.Text);
FileInfo[] Files = dinfo.GetFiles("*.doc");
foreach (FileInfo file in Files)
{
listView1.Items.Add(file.Name);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
label2.Text contains the directory that houses the files. What I need is for a second listView to display a list of documents housed in another directory to display if the file does not appear in the first list view.
The second directory contains templates where as the first directory contains completed documents. The names are different in each directory, but they are similar. For example a completed document displayed in the first listView may be called DEFECT1_AA09890.doc. It's template may be called 05DEFECT.doc.
It is easy enough to display the contents of the template directory using this code:
private void templateDocuments()
{
string path = #"\\directoryname\foldername";
try
{
DirectoryInfo dinfo = new DirectoryInfo(path);
FileInfo[] Files = dinfo.GetFiles("*.doc");
foreach (FileInfo file in Files)
{
listView2.Items.Add(file.Name);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
But this does not compare contents and display based on the results.
Long story short, I want to display the contents of a directory in a listView, compare it to the contents of another directory, and display in a second listView what does not appear in the first.
Any help would be much appreciated.
Cheers.
Before adding file names to listView2, you need to check whether you already added them to listView1. One way of doing that is to store the files in listView1 in a HashSet<string>, then checking that before adding to listView2. Something like this should work:
private void filesAndTemplates()
{
string path = #"\\directoryname\foldername";
HashSet<string> files = new HashSet<string>();
try
{
DirectoryInfo dinfo = new DirectoryInfo(label2.Text);
FileInfo[] Files = dinfo.GetFiles("*.doc");
foreach (FileInfo file in Files)
{
files.Add(file.Name);
listView1.Items.Add(file.Name);
}
dinfo = new DirectoryInfo(path);
Files = dinfo.GetFiles("*.doc");
foreach (FileInfo file in Files)
{
if (files.Contains(file.Name))
{
continue; // We already saw this file
}
listView2.Items.Add(file.Name);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
EDIT
If you want inexact matching, you need to reduce the file name to its essence -- remove any decorations, which in your case looks to be one (or both) of
Leading digits
Underscore followed by whatever
The essence of 01hello_world.doc would thus be hello.
Regex should fit the bill quite nicely -- although the exact definition of the regular expression would depend on your exact requirements.
Define the Regex and a transformation method somewhere suitable:
private static readonly Regex regex = new Regex(
#"[0-9]*(?<core>[^_]+)(_{1}.*)?", RegexOptions.Compiled);
private static string Transform(string fileName)
{
int extension = fileName.LastIndexOf('.');
if (extension >= 0)
{
fileName = fileName.Substring(0, extension);
}
Match match = regex.Match(fileName);
if (match.Success)
{
return match.Groups["core"].Value;
}
return fileName;
}
Then modify the original method to transform the filename before adding files to the HashSet and before checking for their presence:
DirectoryInfo dinfo = new DirectoryInfo(label2.Text);
FileInfo[] Files = dinfo.GetFiles("*.doc");
foreach (FileInfo file in Files)
{
files.Add(Transform(file.Name)); // Here!
listView1.Items.Add(file.Name);
}
dinfo = new DirectoryInfo(path);
Files = dinfo.GetFiles("*.doc");
foreach (FileInfo file in Files)
{
if (files.Contains(Transform(file.Name))) // Here!
{
continue;
}
listView2.Items.Add(file.Name);
}
Note the two calls to Transform.

C# Directory.GetFiles() only showing one file in the list?

I am trying to learn C#, I am starting with some simple stuff.
I am trying to create a simple program that will read all files in a directory which are .XLS extension. I seem to have it working partially, but it only reads the file it sees.
I thought the foreach statement would take care for this and list them all but it doesn't seem to work.
If anyone could put me in the right direction I would really appreciate it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GetFiles();
}
private void GetFiles()
{
List<String> Myfiles = new List<string>();
string[] allFiles = System.IO.Directory
.GetFiles(#"C:\Users\Dave\Desktop\STUFF", "*.*");
if (allFiles.Length > 0)
{
try
{
foreach (string filename in allFiles)
{
this.richTextBox1.Text = filename.ToString();
}
}
catch (SystemException excpt)
{
this.richTextBox1.Text = excpt.Message;
}
}
}
Filter file for xls:
string[] allFiles = System.IO.Directory.GetFiles(#"C:\Users\Dave\Desktop\STUFF", "*.xls");
and update your try block code as :
try
{
this.richTextBox1.Text= string.Join(Environment.NewLine, allFiles);
//foreach (string filename in allFiles)
//{
// this.richTextBox1.Text = filename.ToString();
//}
}
I think it may be caused by this line:
this.richTextBox1.Text = filename.ToString();
You're essentially overwriting the text of the textbox each time, causing only the last filename being written to the richtextbox. You should be appending the filename string to the richTextBox rather than assigning.
from a quick look I think your issue is here:
this.richTextBox1.Text = filename.ToString();
you are assigning the text property with the last loop iteration rather than appending a new line for each file.
try to debug the for loop, do you have multiple iterations?
Because you want xls files, update this line:
string[] allFiles = System.IO.Directory.GetFiles(#"C:\Users\Dave\Desktop\STUFF", "*.xls");
You see probably one file in the edit box. Therefore, update the line:
this.richTextBox1.AppendText(filename + Environment.NewLine);

To get selected list box value with folder path

I have a list box and its populated by this method,
private void ToReadFromExcel_Load(object sender, EventArgs e)
{
string folderpath = #"\\gibson\users";
// Call the method to show available files
PopulateListBox(ExcelListBox, folderpath, "*.csv");
}
// To populate list box with csv files from given path
private void PopulateListBox(ListBox lsb, string Folder, string FileType)
{
DirectoryInfo dinfo = new DirectoryInfo(Folder);
FileInfo[] Files = dinfo.GetFiles(FileType);
foreach (FileInfo file in Files)
{
lsb.Items.Add(file.Name);
}
}
String strItem;
foreach (Object selecteditem in ExcelListBox.SelectedItems)
{
strItem = selecteditem as String;
MessageBox.Show(strItem);
}
// read csv file information and insert into detail table
string filepath = #"\\gibson\users\CampManager.csv";
StreamReader sr = new StreamReader(filepath);
I hard coded the file path now, but I need to pass the filepath that was selected in the listbox. I have the file name in the variable stritem. If I want to pass the whole folder path how would I do that?
There is an ideal way. You should, instead of adding the FileInfo object's Name, should add the FileInfo object itself. So later you will be able to retrieve any piece of info related to that object, in your case say size, parent folder etc, and not just file name. Do it like this:
// To populate list box with csv files from given path
private void PopulateListBox(ListBox lsb, string Folder, string FileType)
{
DirectoryInfo dinfo = new DirectoryInfo(Folder);
FileInfo[] Files = dinfo.GetFiles(FileType);
foreach (FileInfo file in Files)
{
lsb.Items.Add(file); //<-- note here
}
}
String strItem;
foreach (FileInfo selecteditem in ExcelListBox.SelectedItems)
{
StreamReader sr = new StreamReader(selecteditem.FullName);
//or whatever
}
One thing you should take care of here is to set the DisplayMember property of the ListBox like this:
ExcelListBox.DisplayMember = "Name";
What this does is to set the what property of the object in the listbox should be displayed. So here you choose FileInfo.Name which is what you want. This is how typically custom objects are added to ListBoxes in WinForms. You do not add just the string part of it typically. Akin to DisplayMember, there is also ValueMember property which is used to assign a value for each object, probably some id or so, but in your case nothing.
Few suggestions, 1) If you're using .NET 4, then use EnumerateFiles instead of GetFiles. The former is lazy and only yields a result when you start enumerating them (not beforehand), so it should be faster.
foreach (FileInfo file in dinfo.EnumerateFiles(FileType)) //<-- note here
{
lsb.Items.Add(file);
}
2) Use a using clause to dispose your stream reader properly, since that wont lock your file. It's always a good practice to make use of using. Its better on eyes than manual closing and disposing! Like this or so:
foreach (FileInfo selecteditem in ExcelListBox.SelectedItems)
{
using(StreamReader sr = new StreamReader(selecteditem.FullName))
{
//your code here
}
}

adding items to a radlistbox

I am trying to add items from FileInfo into my RadListBox although I am not able to, I tried casting the file into a RadListBoxItem object, but I get the error that it can not convert a string to a radlistboxitem. Can someone shed a little light? thanks.
DirectoryInfo dir = new DirectoryInfo(Path.GetFullPath(fp));
lb_Files.Items.Clear();
foreach (FileInfo file in dir.GetFiles())
{
RadListBoxItem rlb = new RadListBoxItem();
rlb = (RadListBoxItem)file.ToString();
//radListBox
lb_Files.Items.Add(rlb.ToString());
}
Try this
DirectoryInfo dir = new DirectoryInfo(Path.GetFullPath(fp));
lb_Files.Items.Clear();
foreach (FileInfo file in dir.GetFiles())
{
lb_Files.Items.Add(new RadListBoxItem(file.ToString(), file.ToString()));
}
No you cannot cast a String object into a RadListBoxItem, you must create a RadListBoxItem using that string as your Value and Text properties:
So replace this:
RadListBoxItem rlb = new RadListBoxItem();
rlb = (RadListBoxItem)file.ToString();
//radListBox
lb_Files.Items.Add(rlb.ToString());
With this:
lb_Files.Items.Add(new RadListBoxItem
{
Value = file.ToString(),
Text = file.ToString()
});

Read file from listbox

I have some code that will load full file names (ex.F:\logs\1234.log) into a listbox depending on the directory the user chooses. When the user selects one or more of the files and clicks the output button, I want the code to read through each selected file. Before, I was using a combobox and the code:
StreamReader sr = new StreamReader(comboBox1.Text);
This obviously does not work for listboxes. What is the simplest way to have the program read the user selected file(s) from the listbox?
To access all selected items in a ListBox you can use the SelectedItems property:
foreach (string value in listBox1.SelectedItems)
{
StreamReader sr = new StreamReader(value);
...
}
If you are choocing one file per time to open, then a solution would be as follows:
string[] files = Directory.GetFiles(#"C:\");
listBox1.Items.Clear();
listBox1.Items.AddRange(files);
Then, to get to the file path selected:
if (listBox1.SelectedIndex >= 0)
{ // if there is no selectedIndex, property listBox1.SelectedIndex == -1
string file = files[listBox1.SelectedIndex];
FileStream fs = new FileStream(file, FileMode.Open);
// ..
}
What you can do it to create a generic list, which will hold all the text from selected files:
void GetTextFromSelectedFiles()
{
List<string> selectedFilesContent = new List<string>();
for (int i = 0; i < listBox1.SelectedItems.Count; i++)
{
selectedFilesContent.Add(ReadFileContent(listBox1.SelectedItems.ToString()));
}
//when the loop is done, the list<T> holds all the text from selected files!
}
private string ReadFileContent(string path)
{
return File.ReadAllText(path);
}
I think in your example when you explicitly said "as simple as possible" to read the file, would be best to use File.ReadAllText() method, better then using StreamReader class.
You should have been more clear in your original question... but if you need to read all the files:
var items = listBox.SelectedItems;
foreach (var item in items)
{
string fileName = listBox.GetItemText(item);
string fileContents = System.IO.File.ReadAllText(fileName);
//Do something with the file contents
}

Categories

Resources