checkedlistbox in C#, display only file name, not full path - c#

I am trying to select a bunch of files and put the names into a checkedlistbox but it always displays the full directory path with the filename. I only want the user to see the file name but I want to preserve the path inside the code so when the user clicks a button the program can still find the files and operate on them.
My question has already been asked on another forum but I can't seem to get the expected results, currently, my code does as follows:
user clicks button_1: User selects folder containing files
all CSV files with only their file name in the checkedlistbox are displayed, with a message box appearing displaying their full paths. The user proceeds to check necessary files.
User clicks button_2: Displays a message box with the checked filenames, but not the full file paths, of which I am trying to retrieve.
Any help in this would be most appreciated thanks.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace SelectFiles
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkedListBox1.CheckOnClick = true;
}
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
checkedListBox1.Items.Clear();
string[] files = Directory.GetFiles(fbd.SelectedPath);
List<FileInfo> excel_files = new List<FileInfo>();
foreach (string file in files)
{
FileInfo f = new FileInfo(file);
MessageBox.Show((f.FullName));
excel_files.Add(f);
}
BindingSource bs = new BindingSource();
bs.DataSource = excel_files;
checkedListBox1.DataSource = bs;
checkedListBox1.DisplayMember = "Name";//Path.GetFileName(file);
}
}
private void button2_Click_1(object sender, EventArgs e)
{
List<FileInfo> list_all_excelfiles = new List<FileInfo>();
foreach (FileInfo item in checkedListBox1.CheckedItems)
{
list_all_excelfiles.Add(item);
MessageBox.Show(Path.GetFileName(item.FullName));
}
}
}
}

If I understood correctly, you want to get the file full path when user click on button2.
This can be achieved by modifying your code.
In the button2 event, are asking for Path.GetFileName
Change it to
Path.GetFullPath
which will return the full path of the file.
Your code should be looks like :
private void button2_Click_1(object sender, EventArgs e)
{
List<FileInfo> list_all_excelfiles = new List<FileInfo>();
foreach (FileInfo item in checkedListBox1.CheckedItems)
{
list_all_excelfiles.Add(item);
MessageBox.Show(Path.GetFullPath(item.Name));
}
}
Note : in your code, you are trying to clear the items from checkedListBox1 by Clear() method but you'll face an exception.
System.ArgumentException: 'Items collection cannot be modified when
the DataSource property is set.'
and that's because you added a data source already !
instead use :
checkedListBox1.DataSource = null;

Related

How to make a program that will open a certain picture in the picturebox, depending on the text entered in the textbox. C# forms

I don't understand what to do
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1 = "France")
{
pictureBox1.Image = Image.FromFile(#"C:\user\proga ot alejandro\1.jpg");
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
I should make programm when i text a country name in textbox it will open a picture in picture box
I need help please. I would be kicked from the university if i wont make that programm.
Try this code in your Text Changed event - then build on all your other countries that are needed.
if (textBox1.Text.ToLower() == "france")
{
pictureBox1.Image = Image.FromFile(#"C:\path to picture");
}
else if (textBox1.Text.ToLower() == "us")
{
pictureBox1.Image = Image.FromFile(#"C:\path to picture");
}else if(continue on...){}
Here are a few suggestions to put you on the right track (but please make sure that the final code you turn into "university" is something you can explain and justify ;).
First, put the images into a folder and set their properties to Copy if Newer so that they can be read from a known path at runtime.
This makes it easy to capture a list of the image file names when you start your program.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
var folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");
// Make an array of the image file names so you can search it.
_images =
Directory
.GetFiles(folder)
.ToArray();
textBoxSearch.TextChanged += ontextBoxSearchChanged;
}
}
private string[] _images;
Then, when the text changes, you can use a System.Linq expression or some other method to search this list for matches (making sure not to consider the extension or the folder path). Just make certain that this search functionality "knows what to do" if it finds multiple matches.
private void ontextBoxSearchChanged(object sender, EventArgs e)
{
// Do not block on this event.
BeginInvoke((MethodInvoker)delegate
{
string[] matches;
if(string.IsNullOrWhiteSpace(textBoxSearch.Text))
{
matches = new string[0];
}
else
{
// Use Linq to detect matches
matches =
_images
.Where(_ =>
Path.GetFileNameWithoutExtension(_)
.Contains(textBoxSearch.Text)
).ToArray();
}
labelMatchCount.Text = $"{matches.Length} matches";
if(matches.Length.Equals(1))
{
// Found a single match
labelMatchCount.Visible = false;
pictureBox.Image = Image.FromFile(matches.First());
}
else
{
// Found multiple matches
pictureBox.Image = null;
labelMatchCount.Visible = true;
}
});
}

print Csv data in DataGridview C# without using olehDBconnect

I'm trying to import CSV and display the data in DataGridView by using the way that i can understand.
Here is the code and the explanation that i understand how it works so far.
Please do correct me if i miss understand.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace test2
{
public partial class Form1 : Form
{
//Open the choose GUI to choose the file that we want to import
OpenFileDialog openFile = new OpenFileDialog();
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
//if open successfully, then apply streamReader to it
if (openFile.ShowDialog() == DialogResult.OK)
{
StreamReader sr = new StreamReader(openFile.FileName);
//read the data in the file by using readLine
var rl = sr.ReadLine();
// If the rl is not null, then print (is it correct?)....
if(rl != null)
{
///code to print data
}
}
}
//filter out the csv file.
private void Form1_Load_1(object sender, EventArgs e)
{
openFile.Filter = "CSV|*.csv";
}
}
}
Now, i'm trying to print the data.
I know i need to use DataGridView.DataSource to print the data(correct me if i'm wrong) but i have no idea how to apply.
So, is my explain is true or is there anything i have add???
--beginner.
Sample data image.
You can build a List (of string, or whichever data type you want) and use it as DataSource. Assuming the x:name of your DataGridView is dgv.
private void Button1_Click(object sender, EventArgs e)
{
//if open successfully, then apply streamReader to it
if (openFile.ShowDialog() == DialogResult.OK)
{
List<string[]> rows = System.IO.File.ReadAllLines(openFile.FileName).Select(x => x.Split(',')).ToList();
System.Data.DataTable dt = new System.Data.DataTable();
List<string> headerNames = rows[0].ToList();
foreach (var header in headerNames)
{
dt.Columns.Add(headers);
}
foreach (var x in rows.Skip(1))
{
if (x.SequenceEqual(headerNames)) //linq to check if 2 lists are have the same elements (perfect for strings)
continue; //skip the row with repeated headers
dt.Rows.Add(x);
}
dgv.DataSource = dt;
}
}
Remember to add using System.Linq;.
Do ask if any part is unclear. You can add more checking to the 2nd foreach loop (e.g. check if all the items in the row are empty).
My answer is based on: Faster way of reading csv to grid
For best way of checking 2 lists equality:
Check if two lists are equal

C# Write Data to a text File

I got a homework assignment here. I've created a form with 4 text boxes for data entry, Account #, First Name, Last Name, Balance. I have four buttons, Create File, Save data to file, clear, and exit. Basically all the program does is create a text file, then I input my data into the text boxes, then I hit save data file which will write the data to the text file I have created. Clear and Exit are already done, and I have the program working as far as creating the text file, now I just need someone to point me in the right direction on how to actually write the data I entered into the text file. Here is my code, Thanks in advance
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Chapter_17_Ex.Sample_1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCreate_Click(object sender, EventArgs e)
{
SaveFileDialog file = new SaveFileDialog();
file.FileName = "client.txt";
file.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
file.ShowDialog();
StreamWriter filewrite = new StreamWriter(file.FileName);
}
private void btnSave_Click(object sender, EventArgs e)
{
TextWriter file = new TextWriter
}
private void btnClear_Click(object sender, EventArgs e)
{
txtAccount.Clear();
txtBalance.Clear();
txtFirstName.Clear();
txtLastName.Clear();
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
You're on the right track with creating that StreamWriter instance. What you want to do now is use the WriteLine() method of that class. It's also a good idea to wrap that StreamWriter instance in a using block:
private void btnCreate_Click(object sender, EventArgs e)
{
SaveFileDialog file = new SaveFileDialog();
file.FileName = "client.txt";
file.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
file.ShowDialog();
using(StreamWriter filewrite = new StreamWriter(file.FileName))
{
filewrite.WriteLine( String.Format("First Name is {0}", txtFirstName.Text) );
//use Write() or WriteLine() again as needed.
}
}
For the file create you can use:
File.Create(file.FileName).Close(); // replace the StreamWriter code with this
For the simplest way to write into that file:
string line = string.Join(",", txtAccount.Text, txtBalance.Text, txtFirstName.Text, txtLastName.Text) + System.Environment.NewLine;
File.AppendAllText(file.FileName, line);
You also need to move the 'SaveFileDialog file' to be a class field, not a method local variable.
You didn't specify the output format. What I chose is CSV... but there's no "escaping" of the input, which needs to be done to prevent inputting commas from messing up the output. That part is up to you.
Note the use of File.Create and File.AppendAllText - these save you from having to put using around the actual I/O.

Log deleted files when button is clicked? Log all files (deleted and undeleted)

I am writing an application to delete file on a test folder that are over 6 months, the application works fine as I have tested it, I wanted to create a log file to keep track of the name of the deleted files for audit purpose.
but with the scirpt below it does record all the files (deleted and undeleted), all I need is just record the date and time and the name of the deleted files.
Thank you
Script Below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Delete_PDF_Files
{
public partial class Form1 : Form
{
private string strLogText;
public Form1()
{
InitializeComponent();
}
private void btnCheck_Click(object sender, EventArgs e)
{
// check the number of file in the CPS directory on S drive
listBox1.Items.Clear();
string[] files = System.IO.Directory.GetFiles(#"C:\test\"); // #"S:\CPS Papers\"
this.listBox1.Items.AddRange(files);
textBox1.Text = listBox1.Items.Count.ToString();
}
// delete button to delete files over 6 months from CPS folder
private void btnDelete_Click(object sender, EventArgs e)
{
string[] files = System.IO.Directory.GetFiles(#"C:\test\"); //S:\CPS Papers test C:\test\
foreach (string file in files)
{
System.IO.FileInfo fi = new System.IO.FileInfo(file);
if (fi.LastWriteTime < DateTime.Now.AddMonths(-6))
fi.Delete();
// Create a writer and open the file: //C:\test\log
System.IO.StreamWriter log;
if (!System.IO.File.Exists("C:\\test\\log\\logfile.txt"))
{
log = new System.IO.StreamWriter("C:\\test\\log\\logfile.txt");
}
else
{
log = File.AppendText("C:\\test\\log\\logfile.txt");
}
// Write to the file:
log.WriteLine(DateTime.Now);
log.WriteLine(strLogText);
log.WriteLine();
log.WriteLine();
// Close the stream:
log.Close();
}
}
// Exit button
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Replace you delete code with this one:
private void btnDelete_Click(object sender, EventArgs e)
{
string[] files = System.IO.Directory.GetFiles(#"C:\test\"); //S:\CPS Papers test C:\test\
foreach (string file in files)
{
System.IO.FileInfo fi = new System.IO.FileInfo(file);
//if (fi.LastAccessTime < DateTime.Now.AddMonths(-3))
if (fi.LastWriteTime < DateTime.Now.AddMonths(-6))
{
fi.Delete();
using (StreamWriter writer = File.AppendText("C:\\test\\log\\logfile.txt"))
{
writer.Write("File: " + file + " deleted at : "+DateTime.Now);
writer.WriteLine("----------------------------------------------------");
writer.Flush();
writer.Close();
}
}
}
}
Instead of using custom logging as you are doing I would recommend that you use a good library like Log4Net. Why reinvent the wheel? I know that it has a small learning curve time but once you get to know you you can easily integrate it in any new projects.
By just adding a config section to your app.config as given here and a few lines of code you should be ready to go.
A good tutorial on Log4Net can be found here

How to switch directories using C#?

(This is a continuation of the discussion on this question)
I have code that looks in a specific folder in the C: drive. It can tell what is in that folder, and gets what the user selects. But the problem is switching to a new Data folder to get the code from.
All the code necessary to run the program is kept in the Data folder, the company I am interning with wants to be able to switch Data folders so they can show their software off better, and have it geared towards whoever they are showing it to.
So basically my program needs to switch data folders so the company can show their software better.
Ill post all my code, its not much, so you guys can look at all of it.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string defaultPath = #"C:\Mavro\MavBridge\";
public Form1()
{
InitializeComponent();
dropdown();
}
private void button1_Click(object sender, EventArgs e)
{
//some sort of code to switch directory before close goes here
MessageBox.Show("Data folder has been changed.", "Done");
Application.Exit();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string path = comboBox1.SelectedItem.ToString();
defaultPath = path;
}
private void buttonTest_Click_1(object sender, EventArgs e)
{
}
public void dropdown()
{
string[] dispDirectories = Directory.GetDirectories(defaultPath, "Data*");
comboBox1.Items.Clear();
comboBox1.Items.AddRange(dispDirectories);
}
}
}
To answer your second question, about stripping the Default Path from the combobox display
//Where you load your directories
string[] dispDirectories = Directory.GetDirectories(#"c:\", "*.*");
// so here we will iterate through all the directories found and remove the default path from it.
for (int i=0;i<dispDirectories.Count();i++)
dispDirectories[i]=dispDirectories[i].Remove(0, defaultPath.Length);
Then where you set your path change to this. Because we removed the default Path we now have to add it again.
string path = defaultPath+comboBox1.SelectedItem.ToString();
defaultPath = path;
Look at your button1_Click method. Change your message Box to
MessageBox.Show("Data folder has been changed to "+defaultPath,"Done");
private void button1_Click(object sender, EventArgs e)
{
//some sort of code to switch directory before close goes here
MessageBox.Show("Data folder has been changed to "+defaultPath,"Done");
Application.Exit();
}
you will see that you have already changed the default Path
EDIT(#K'Leg Suggestion to make answer more clear): If you want to get the subdirectories, after you make your first selection you should call method dropdown() in comboBox1_SelectedIndexChanged
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string path = comboBox1.SelectedItem.ToString();
defaultPath = path;
dropdown();
}
A better would be receive default path as parameter in dropdown(), something on the following line
public void dropdown(string defaultPath)
{
string[] dispDirectories = Directory.GetDirectories(defaultPath, "Data*");
comboBox1.Items.Clear();
comboBox1.Items.AddRange(dispDirectories);
}
and then call dropdown method in comboBox1_SelectedIndexChanged as:
dropdown(comboBox1.SelectedItem.ToString());
EDIT: (based on the comments on OP) the problem is the filter you are specifying for the GetDirecotries, for every path you pass to it, it looks for folder starting with Data and then any characters, for example Data.Apple, now when you set your path to Data.Apple, there it again looks for folder which should start with Data, you may pass the filter in the dropdown method on some condition
you may define the method dropdown as:
public void dropdown(string defaultPath, string filter)
{
string[] dispDirectories = Directory.GetDirectories(defaultPath, filter);
comboBox1.Items.Clear();
comboBox1.Items.AddRange(dispDirectories);
}
Then you can call the dropdown for the first time as :
public Form1()
{
InitializeComponent();
dropdown(#"C:\Mavro\MavBridge\","Data*");
}
and then in the SelectedIndexChanged as:
dropdown(comboBox1.SelectedItem.ToString(),"*"); // * means select all

Categories

Resources