Checkedlistbox refresh not working - c#

I have this method to open and fill checkedlistbox.
void Show_files()
{
FolderBrowserDialog FBD = new FolderBrowserDialog();
if (FBD.ShowDialog() == DialogResult.OK)
{
checkedListBox1.Items.Clear();
string[] files = Directory.GetFiles(FBD.SelectedPath);
string[] dirs = Directory.GetDirectories(FBD.SelectedPath);
foreach (string file in files)
{
checkedListBox1.Items.Add(file);
}
foreach (string dir in dirs)
{
checkedListBox1.Items.Add(dir);
}
}
}
and then button to delete selected files.
private void button1_Click(object sender, EventArgs e)
{
foreach (var item in checkedListBox1.CheckedItems.OfType<string>().ToList())
{
DialogResult dialogResult = MessageBox.Show("Czy na pewno chcesz usunać zaznaczone pliki", "Czy na pewno chcesz usunać zaznaczone pliki?", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
File.Delete(item);
}
}
MessageBox.Show("Usunięto");
checkedListBox1.Refresh(); // here should refresh list of folder content
}
I've tried to clear and add items again in loop (if items count not null) in method Show_files() but it hasn't worked. Hide and show neither. I don't want to open folder browser again. It has to happen automatically.

You aren't removing the item from the control:
if (dialogResult == DialogResult.Yes)
{
File.Delete(item);
checkedListBox1.Items.Remove(item);
}
Best to put some Try...Catch blocks around such operations.

Related

Get and return filepath by foreach

I want to make a program to able to save every file path which the user selected.
after that do some prosses for each file. for example, convert video file one by one.
Could you tell me why foreach does not work?
private void btnInput_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialogInput = new OpenFileDialog();
openFileDialogInput.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
openFileDialogInput.Filter = "Video Files|*.mp4|TS Files|*.ts";
openFileDialogInput.Multiselect = true;
openFileDialogInput.FilterIndex = 1;
DialogResult result = openFileDialogInput.ShowDialog();
string [] inputPath = openFileDialogInput.FileNames;
foreach (var item in inputPath)
{
item;
}
}
inputPath gets all file paths that the user selected. but I don't know how can I get them, one by one and make some prosses on them.
You Can try this:
private void AddWatermark(string videoFilePath)
{
// Add your logic here to add watermark
}
And in the foreach loop:
foreach (var item in inputPath)
{
AddWatermark(item);
}

Deleting .png File through ListView

I am making an application for personal use that will organize .png files and will let me remotely delete them from the directory through the application (through a ListView).
I have a snippet that will delete the file from the ListView, but not from the actual file directory. I want to be able to do both when I click delete.
private void deleteToolStripMenuItem1_Click(object sender, EventArgs e)
{
if (MessageBox.Show("This will delete the file from the folder. Are you sure?", "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) == DialogResult.Yes)
for (int i = fileDisplayListView.SelectedItems.Count - 1; i >= 0; i--)
{
ListViewItem item = fileDisplayListView.SelectedItems[i];
fileDisplayListView.Items[item.Index].Remove();
File.Delete(fbd.SelectedPath + fileDisplayListView.Items.ToString());
}
}
Additional snippet for more information..
private void openToolStripButton_Click(object sender, EventArgs e)
{
fbd.ShowDialog();
DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
directoryPath.Text = "Directory: " + fbd.SelectedPath;
FileInfo[] Files =
di.GetFiles("*.PNG*", SearchOption.AllDirectories);
if (Files.Length == 0)
MessageBox.Show("No .png files found in directory...", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Question);
fileDisplayListView.Items.Clear();
foreach (FileInfo f in Files)
{
ListViewItem item = new ListViewItem(f.Name);
this.fileDisplayListView.Items.Add(f.Name);
}
this.fileDisplayListView.View = View.Details;
this.fileDisplayListView.Refresh();
}
The last part of it, File.Delete(fbd.SelectedPath + fileDisplayListView.Items.ToString());
is not functional. Please help!
This code gets a list of all .jpg files in the directory, adds them to the ListView. By pressing the button it deletes the selected ListView elements and files:
private FileInfo[] files;
public Form1()
{
InitializeComponent();
files = new DirectoryInfo(#"C:\Users\User\Pictures").GetFiles("*.jpg", SearchOption.AllDirectories);
foreach (var file in files)
{
listView1.Items.Add(file.Name);
}
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < listView1.SelectedItems.Count; i++)
{
var curentItem = listView1.SelectedItems[i];
foreach (FileInfo file in files)
{
if (curentItem.Text == file.Name)
{
listView1.Items.Remove(curentItem);
file.Delete();
i--;
}
}
}
}
This is the snippet I used to fix the application. It is a lot more directly related to how I am approaching the problem.
if (MessageBox.Show("This will delete the file from the folder. Are you sure?", "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) == DialogResult.Yes)
for (int i = fileDisplayListView.SelectedItems.Count - 1; i >= 0; i--)
{
ListViewItem item = fileDisplayListView.SelectedItems[i];
string fpath = string.Empty;
fileDisplayListView.Items[item.Index].Remove();
fpath = fbd.SelectedPath.ToString() + "\\" + item.Text;
File.Delete(fpath);
}

Overwrite file only works once

I have a simple program that copies files and directories from one place to another. I have it set-up that if there are any exceptions (such as if access to the path is denied) it will create a log file with the error.
I have a button that when pressed, performs the copy action. Everything works fine the first time I press the button and the log file is either created or overwritten with the appropriate error messages.
However, if I press the button a second time, the text file is not overwritten and instead the error messages append. If I close out of my program and run it again, the file is overwritten on the first button press. Any thoughts would be greatly appreciated.
target is a string filepath which I'm getting from a FolderBrowserDialog and taking the selected path and setting it to a textbox. loglist is just a simple List<string> I'm using to store the error messages from any exceptions that occur during the copy process.
public partial class Form1 : Form
{
static List<string> logList = new List<string>();
public Form1()
{
InitializeComponent();
}
private static void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
if (source.FullName.ToLower() == target.FullName.ToLower())
return;
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
foreach (FileInfo fi in source.GetFiles())
{
try
{
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
catch (Exception ex)
{
logList.Add(ex.Message);
}
}
foreach (DirectoryInfo diSourceSub in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSub.Name);
CopyAll(diSourceSub, nextTargetSubDir);
}
}
private void directoryPickerBtn1_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderDialog = new FolderBrowserDialog();
DialogResult folderResult = folderDialog.ShowDialog();
if (folderResult == DialogResult.OK)
{
directoryTextbox1.Text = folderDialog.SelectedPath;
}
}
private void directoryPickerBtn2_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderDialog = new FolderBrowserDialog();
DialogResult folderResult = folderDialog.ShowDialog();
if (folderResult == DialogResult.OK)
{
directoryTextbox2.Text = folderDialog.SelectedPath;
}
}
private void copyBtn_Click(object sender, EventArgs e)
{
string source = (directoryTextbox1.Text);
string target = (directoryTextbox2.Text);
DirectoryInfo dirSource = new DirectoryInfo(source);
DirectoryInfo dirTarget = new DirectoryInfo(target);
try
{
CopyAll(dirSource, dirTarget);
if (logList.Count > 0)
{
using (StreamWriter sw = new StreamWriter(target + #"\log.txt", false))
{
foreach (string error in logList)
{
sw.WriteLine(error);
}
}
}
DialogResult result = MessageBox.Show("Copy Succeeded", "Success");
if (result == DialogResult.OK)
{
string myPath = dirTarget.ToString();
System.Diagnostics.Process prc = new System.Diagnostics.Process();
prc.StartInfo.FileName = myPath;
prc.Start();
}
}
catch (Exception)
{
MessageBox.Show("Copy Failed", "Failed");
}
}
}
}
As #Reza Aghaei pointed out in comments, the problem is that you do not clear the logList.
The file gets created anew every time, but each time you click the Copy button, the loglist still contains the results of the previous copy action.
So you need to clear the list when starting a new copy:
private static void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
logList.Clear();
// ...
From your code it seems that you never clear the logList, this means that it appears the file is being appending because the logList still contains all of the old entries.
You'll need to clear the list between copies if you only want relevant entries to that copy, either before you start copying or after you finish writing the file.
This would be better as a separate method
try
{
CopyAll(dirSource, dirTarget);
SaveLog(target + #"\log.txt");
ClearLog();
//...
}
private void SaveLog(string filename)
{
if (logList.Count > 0)
{
FileStream fs = File.Open(target + #"\log.txt", FileMode.Create);
using (StreamWriter sw = new StreamWriter(fs))
{
foreach (string error in logList)
{
sw.WriteLine(error);
}
}
}
}

Emptying a listbox programmatically

I want to clear listbox everytime when addImages button is clicked which adds new items to it but I am facing problem in clearing it. Following is my code:
private void addImages_Click(object sender, RoutedEventArgs e)
{
FileInfo Images;
string[] filenames = null;
System.Windows.Forms.FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
folderDlg.ShowNewFolderButton = true;
System.Windows.Forms.DialogResult result = folderDlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
filenames = System.IO.Directory.GetFiles(folderDlg.SelectedPath);
foreach (string image in filenames)
{
Images = new FileInfo(image);
if(Images.Extension.ToLower() == ".png" || Images.Extension.ToLower() == ".jpg" || Images.Extension.ToLower() == ".gif" || Images.Extension.ToLower() == ".jpeg" || Images.Extension.ToLower() == ".bmp" || Images.Extension.ToLower() == ".tif")
{
ImageList.Items.Add(new LoadImages(new BitmapImage(new Uri(image))));
}
}
}
}
I have tried ImageList.items.clear(), BindingOperations.ClearAllBindings(ImageList) but these removed items first time only when button is clicked next time onwards they don't clear the list. I want list to be cleared everytime when button is clicked.
This code below should work properly. the only thing that might be problematic
private void addImages_Click(object sender, RoutedEventArgs e)
{
ImageList.Items.Clear();
RefreshList();
FileInfo Images;
string[] filenames = null;
System.Windows.Forms.FolderBrowserDialog folderDlg = new System.Windows.Forms.FolderBrowserDialog();
folderDlg.ShowNewFolderButton = true;
System.Windows.Forms.DialogResult result = folderDlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
filenames = System.IO.Directory.GetFiles(folderDlg.SelectedPath);
foreach (string image in filenames)
{
Images = new FileInfo(image);
if(new string[]{".png", ".jpg", ".gif", ".jpeg", ".bmp", ".tif"}.Contains(Images.Extension.ToLower()))
{
ImageList.Items.Add(new LoadImages(new BitmapImage(new Uri(image))));
}
}
}
RefreshList();
}
private void RefreshList()
{
// Force visual refresh of control
ImageList.Refresh();
}
*note i cleaned up the extension validation
Edit : I just noticed you talk about Bindings. well you problem is easy then. you cannot clear a list binded to a control. the control will keep original source. You can only UPDATE a binding source otherwise you need to manually update the binding.
Binding on collection is a like a climbing.
Control is the person
Ropes are the DataSource(collection)
Mountain is your model
If in your model you clear (cut) the source (all ropes)
the Control (person) still hold the source (ropes)
If you want the control (person) to have a new source (rope)
You need to add a new one so he can jump on it an remove old ones.
ListBox.Items.Clear should clear the list, if you need that to happen every time the button is clicked then you need it in your event handler i.e.
private void addImages_Click(object sender, RoutedEventArgs e)
{
listBox.Items.Clear();
// do stuff
}
Try this ..
ImageList.Images.Clear();
listBox.Items.Clear();

Loading large amount of text files from a share drive to search for a world. C#

Im trying to perform a search in a share drive that contains at least 90,000 files.
The code below is what I have:
private void button2_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text))
{
MessageBox.Show("No folder: Not listed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
List<string> allFiles = new List<string>();
AddFilesnames(sourceFolder, allFiles);
foreach (string fileName in allFiles)
{
string contents = File.ReadAllText(fileName);
if (contents.Contains(searchword))
{
listBox1.BeginUpdate();
listBox1.Items.Add(fileName);
listBox1.EndUpdate();
label4.Text = (Convert.ToInt32(label4.Text) + 1).ToString();
}
}
if (listBox1.Items.Count == 0)
{
MessageBox.Show("no files");
}
}
}
public void listboxtofile()
{
DialogResult resDialog = dlgSaveFile.ShowDialog();
if (resDialog.ToString() == "OK")
{
FileInfo fi = new FileInfo(dlgSaveFile.FileName);
StreamWriter sw = fi.CreateText();
foreach (string sItem in listBox1.Items)
{
sw.WriteLine(sItem);
}
sw.Close();
}
}
public void AddFilesnames(string sourceDir, List<string> allFiles)
{
string[] fileEntries = Directory.GetFiles(sourceDir);
foreach (string fileName in fileEntries)
{
DateTime from1 = dateTimePicker1.Value.Date;
DateTime to1 = dateTimePicker2.Value.Date;
DateTime creationTime = File.GetCreationTime(fileName);
if (creationTime >= from1 && creationTime <= to1)
{
allFiles.Add(fileName);
}
}
//Recursion
string[] subdirectoryEntries = Directory.GetDirectories(sourceDir);
foreach (string item in subdirectoryEntries)
{
// Avoid "reparse points"
if ((File.GetAttributes(item) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
AddFileNamesToList(item, allFiles);
label4.Text = (Convert.ToInt32(label4.Text) + 1).ToString();
}
}
}
private void button3_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
textBox1.Clear();
}
private void button5_Click(object sender, EventArgs e)
{
listboxtofile();
}
}
}
So far this is working with 3,000 files but I need to have access to a shared drive that contains 90,000 files and when I try to search in the share drive the windows form get frozen. I will really apreciate any help from you all.
My suggestion would be to do any file system work in a separate thread. If you do the file searching in the same thread as your form, Windows has no chance to update the form. You won't be able to update any of your form controls (like listBox1) directly from the new thread, but you can look into delegates and C# threading in general for ways to work around this.
Also, if you just need to search files for a specific word, have you looked into existing tools like grep?

Categories