I am trying to make an app that finds all images on a specific folder (exemple: CR7) and not on all directories. I have a network share and a lot of directories where I can find that specific folder "CR7". I only need images from that CR7 folder. I cand find them and trying to put those results on a datadridview, but without success. Any ideas why filesList does not go to datatable?
Here is the code:
{
public partial class FormProcuraFotos : Form
{
DataTable tableWithPhotos;
public FormProcuraFotos()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += this.Worker_DoWork;
worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// Create the new DataTable to be used
tableWithPhotos = new DataTable();
//Find files on a specific folder (CR7)
string allDir = #"\\share\folder01";
var CR7Directories = Directory.EnumerateDirectories(allDir, "CR7", SearchOption.AllDirectories);
List<string> extensions = new List<string>() { ".jpg", ".bmp", ".png", ".tiff", ".gif" };
List<string> filesList = new List<string>();
foreach (var dir in CR7Directories)
{
List<string> FileNames = new DirectoryInfo(dir).EnumerateFiles(dir)
.Where(x => extensions.Contains(x.Extension))
.Select(x => x.Name).ToList();
filesList.AddRange(FileNames);
}
// And now here we will add all the files that it has found into the DataTable
foreach (string entryFiles in filesList)
{
DataRow row = tableWithPhotos.NewRow();
row[0] = Path.GetFileName(entryFiles);
row[1] = entryFiles;
tableWithPhotos.Rows.Add(Path.GetFileName(entryFiles), entryFiles);
}
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Visible = false;
var formToOpen = new FormResultadosFotos(tableWithPhotos);
formToOpen.Show();
}
}
}
I think you are adding new row to datagridview like a datatable and it doen's work.
With datagridview, you can do:
tableWithPhotos.Rows.Add(Path.GetFileName(entryFiles), entryFiles);
Or [If there is any row in your datagridview], you can do:
DataGridViewRow row = (DataGridViewRow)tableWithPhotos.Rows[0].Clone();
row[0] = Path.GetFileName(entryFiles);
row[1] = entryFiles;
tableWithPhotos.Rows.Add(row);
Please refer this link for more details: DataGridViewRows
Because you are creating new form and add a datagrid to it, then the result is null. You can do as bellow:
option1: make filesList as a member of the class, and create new form base on filesList instead of the DataGridView tableWithPhotos, and add row to DataGridView in FormResultadosFotos similar with common your current code.
var formToOpen = new FormResultadosFotos(filesList);
formToOpen.Show();
option 2: modify your constructor of FormResultadosFotos:
public FormResultadosFotos(DataGridView dataGridView)
{
InitializeComponent();
dataGridView1.Rows.Clear();
foreach (DataGridViewRow row in dataGridView.Rows)
{
dataGridView1.Rows.Add(row.Cells[0].Value, row.Cells[1].Value);
}
}
P/S: Make sure that your DataGridView in your FormResultadosFotos already had 2 columns.
Cheer!
Related
I need to find a lot of files (images) in a specific folder (for exemple CR7), in different directories.
Imagine I have a network share that I have to find and display all images in that specific folder (CR7). CR7 folder can be found in different places like:
\\share\folder01\CR7 or: \\share\folder01\folder02\CR7 or anything else.
What I have is this, but results from filesList dont go to datagridview:
public partial class FormProcuraFotos : Form
{
DataTable tableWithPhotos;
public FormProcuraFotos()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Visible = true;
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += this.Worker_DoWork;
worker.RunWorkerCompleted += this.Worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// Create the new DataTable to be used
tableWithPhotos = new DataTable();
tableWithPhotos.Columns.Add("Filenames");
tableWithPhotos.Columns.Add("Ctrl+C");
//Find files on a specific folder (CR7)
string allDir = #"\\server\folder01";
var CR7Directories = Directory.EnumerateDirectories(allDir, "CR7", SearchOption.AllDirectories);
List<string> extensions = new List<string>() { ".jpg", ".bmp", ".png", ".tiff", ".gif" };
List<string> filesList = new List<string>();
foreach (var dir in CR7Directories)
{
List<string> FileNames = new DirectoryInfo(dir).EnumerateFiles(dir)
.Where(x => extensions.Contains(x.Extension))
.Select(x => x.Name).ToList();
filesList.AddRange(FileNames);
}
// And now here we will add all the files that it has found into the DataTable
foreach (string entryFiles in filesList)
{
DataRow row = tableWithPhotos.NewRow();
row[0] = Path.GetFileName(entryFiles);
row[1] = entryFiles;
tableWithPhotos.Rows.Add(row);
}
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Visible = false;
var formToOpen = new FormResultadosFotos(tableWithPhotos);
formToOpen.Show();
}
}
I think you have to split the execution by following steps:
Get all Directories with name "CR7" under the specified folder by specifying "CR7" as searchPattern.
Now you have all CR7 folder paths, Iterate through those collection and Get List of files and filter them based on the extension list, in each CR7 directory.
Can you please try this and let me know whether it solved your issues:
string allDir = #"\\share\folder01";
var CR7Directories = Directory.EnumerateDirectories(allDir, "CR7", SearchOption.AllDirectories);
List<string> extensions = new List<string>() { ".jpg", ".bmp", ".png", ".tiff", ".gif" };
List<string> filesList = new List<string>();
foreach (var dir in CR7Directories)
{
List<string> FileNames = new DirectoryInfo(dir).EnumerateFiles(dir)
.Where(x => extensions.Contains(x.Extension))
.Select(x => x.Name).ToList();
filesList.AddRange(FileNames);
}
I have a datagridview that is not bound to a table in a database. The datagridview is being populated by the contents of a drop down list and a text box on a button click. I want to prevent the records from being deleted everytime I close the form. Is there a way for the records in the datagridview to be saved without having to create a database table?
Below is my code:
private void btnInsert_Click(object sender, EventArgs e)
{
this.dgInsertedInfo.Rows.Add(ddlVendorID.Text, txtDate.Text);
}
You have many options. Here is a simple solution that uses XML serialization.
Note that it makes a few assumptions:
The data all are strings
The DataGridView already has all the columns
To save the other data types you should create a serializable structure!
private void saveButton_Click(object sender, EventArgs e)
{
List<List<string>> data = new List<List<string>>();
foreach(DataGridViewRow row in dgInsertedInfo.Rows)
{
List<string> rowData = new List<string>();
foreach (DataGridViewCell cell in row.Cells)
rowData.Add(cell.FormattedValue.ToString());
data.Add(rowData);
}
XmlSerializer xs = new XmlSerializer(data.GetType());
using (TextWriter tw = new StreamWriter(yourFileName))
{
xs.Serialize(tw, data);
tw.Close();
}
}
private void loadButton_Click(object sender, EventArgs e)
{
List<List<string>> data = new List<List<string>>();
XmlSerializer xs = new XmlSerializer(data.GetType());
using (TextReader tr = new StreamReader(yourFileName))
data = (List<List<string>>) xs.Deserialize(tr);
foreach (List<string> rowData in data)
dgInsertedInfo.Rows.Add(rowData.ToArray());
}
You can write your OWN class and save it as a setting-property.
Class Settings:
namespace MyNamespace
{
public class Settings
{
private ObservableCollection DataGridItemsProp;
public ObservableCollection DataGridItems
{
get { return DataGridItemsProp; }
set { DataGridItemsProp = value; }
}
}
}
Get and save your setting:
//get settings
var datagrid = Properties.Settings.Default.UserSettings;
//save settings
Properties.Settings.Default.UserSettings= datagrid;
Properties.Settings.Default.Save();
I need help on a thing, ive been populating a listview via background worker but it appears it had a row count at the end of the loop but the data for is not showing visually on the listview. i really dont know what is happening.
After the background worker process is done. ive put a message box to show the listview item count but it shows no data on listview. Please see picture.
Thank you
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
listView1.View = View.Details;
DataTable dtdt = new DataTable();
dtdt = qr.history(); // query in sql to datatable
for (int i = 0; i < dtdt.Rows.Count; i++)// loop data to listviewitem
{
DataRow dr = dtdt.Rows[i];
ListViewItem listitem = new ListViewItem(dr["custnum"].ToString());
listitem.SubItems.Add(dr["custname"].ToString().Trim());
listitem.SubItems.Add(dr["ratecable"].ToString().Trim());
listitem.SubItems.Add(dr["rateinternet"].ToString().Trim());
listitem.SubItems.Add(dr["rateext"].ToString().Trim());
listitem.SubItems.Add(dr["status"].ToString().Trim());
listitem.SubItems.Add(dr["classname"].ToString().Trim());
listitem.SubItems.Add(dr["SVCstadd"].ToString().Trim());
listitem.SubItems.Add(dr["SVCctadd"].ToString().Trim());
listitem.SubItems.Add(dr["svctelno"].ToString().Trim());
listitem.SubItems.Add(dr["bilstadd"].ToString().Trim());
listitem.SubItems.Add(dr["bilctadd"].ToString().Trim());
listitem.SubItems.Add(dr["billtel"].ToString().Trim());
listitem.SubItems.Add(dr["billtel2"].ToString().Trim());
listitem.SubItems.Add(dr["fax"].ToString().Trim());
listitem.SubItems.Add(dr["zoneno"].ToString().Trim());
listitem.SubItems.Add(dr["zoneName"].ToString().Trim());
listitem.SubItems.Add(dr["bookno"].ToString().Trim());
listitem.SubItems.Add(dr["seqno"].ToString().Trim());
listitem.SubItems.Add(dr["Balance"].ToString().Trim());
listitem.SubItems.Add(dr["balance1"].ToString().Trim());
listitem.SubItems.Add(dr["balance2"].ToString().Trim());
listitem.SubItems.Add(dr["balance3"].ToString().Trim());
listitem.SubItems.Add(dr["billamnt"].ToString().Trim());
listitem.SubItems.Add(dr["maxdate"].ToString().Trim());
this.BeginInvoke(new MethodInvoker(delegate { additemtoLV(listitem); }));
}
System.Threading.Thread.Sleep(100);
}
private delegate void additemtoLVdelegat(ListViewItem ls);
public void additemtoLV(ListViewItem ls)
{
if (InvokeRequired)
{
Invoke(new additemtoLVdelegat(additemtoLV), ls);
}
else
{
listView1.Items.Add(ls);
}
}
Further to comments posted please try the below, which should correctly use the GUI thread, and also has basic exception handling in case an unhandled exception is causing the problem :
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
listView1.View = View.Details;
DataTable dtdt = new DataTable();
dtdt = qr.history(); // query in sql to datatable
var listItems = new List<ListViewItem>();
for (int i = 0; i < dtdt.Rows.Count; i++)// loop data to listviewitem
{
DataRow dr = dtdt.Rows[i];
ListViewItem listitem = new ListViewItem(dr["custnum"].ToString());
listitem.SubItems.Add(dr["custname"].ToString().Trim());
listitem.SubItems.Add(dr["ratecable"].ToString().Trim());
listitem.SubItems.Add(dr["rateinternet"].ToString().Trim());
listitem.SubItems.Add(dr["rateext"].ToString().Trim());
listitem.SubItems.Add(dr["status"].ToString().Trim());
listitem.SubItems.Add(dr["classname"].ToString().Trim());
listitem.SubItems.Add(dr["SVCstadd"].ToString().Trim());
listitem.SubItems.Add(dr["SVCctadd"].ToString().Trim());
listitem.SubItems.Add(dr["svctelno"].ToString().Trim());
listitem.SubItems.Add(dr["bilstadd"].ToString().Trim());
listitem.SubItems.Add(dr["bilctadd"].ToString().Trim());
listitem.SubItems.Add(dr["billtel"].ToString().Trim());
listitem.SubItems.Add(dr["billtel2"].ToString().Trim());
listitem.SubItems.Add(dr["fax"].ToString().Trim());
listitem.SubItems.Add(dr["zoneno"].ToString().Trim());
listitem.SubItems.Add(dr["zoneName"].ToString().Trim());
listitem.SubItems.Add(dr["bookno"].ToString().Trim());
listitem.SubItems.Add(dr["seqno"].ToString().Trim());
listitem.SubItems.Add(dr["Balance"].ToString().Trim());
listitem.SubItems.Add(dr["balance1"].ToString().Trim());
listitem.SubItems.Add(dr["balance2"].ToString().Trim());
listitem.SubItems.Add(dr["balance3"].ToString().Trim());
listitem.SubItems.Add(dr["billamnt"].ToString().Trim());
listitem.SubItems.Add(dr["maxdate"].ToString().Trim());
listItems.Add(listitem);
}
this.BeginInvoke(((Action)(() => { listView1.Items.AddRange(listItems.ToArray()); })));
}
catch (System.Exception exc)
{
this.BeginInvoke(((Action)(() => { MessageBox.Show("BackgroundWorker error: " + exc);})));
}
}
I've used one module to read excel files and fill the data from them into a DataTable. This DataTable gets then displayed into a DataGridView form.
With that I have no problems, but the thing is that I want to catch any changes made to that DataTable while it was displayed in the GridView and to save them.
In other words, I want to call a function each time something has been changed on the updated new DataTable (I have no problems, if this would require an additional button (e.g. "Save Changes") as well).
I've read about binding source and adapters, but I am quite confused and cannot get them to work properly. So any help would be appreciated, here's the code.
public partial class MainForm : Form
{
DataTable dTable = new DataTable();
BindingSource bSource = new BindingSource();
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
void Button1Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "d:\\" ;
openFileDialog1.Filter = /*txt files (*.txt)|*.txt|xcel files (*.xcel*)|*.xcel*|*/ "All files (*.*)|*.*" ;
openFileDialog1.FilterIndex = 1;
openFileDialog1.RestoreDirectory = true ;
openFileDialog1.Title = "Choose a file to read";
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
string szChosenFileNameDirectory = openFileDialog1.FileName;
string szChosenFileExtension = szChosenFileNameDirectory.Substring(szChosenFileNameDirectory.LastIndexOf("."), szChosenFileNameDirectory.Length - szChosenFileNameDirectory.LastIndexOf("."));
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
ExcelFile ef = ExcelFile.Load(szChosenFileNameDirectory);
foreach (ExcelWorksheet sheet in ef.Worksheets)
{
foreach(ExcelColumn column in sheet.Columns)
{
if(column.Index == sheet.CalculateMaxUsedColumns())
break;
DataColumn col = new DataColumn();
col.ColumnName = column.Name;
dTable.Columns.Add(col);
}
foreach (ExcelRow row in sheet.Rows)
{
DataRow r = dTable.NewRow();
r.BeginEdit();
foreach (ExcelCell cell in row.AllocatedCells)
{
r[cell.Column.Name] = cell.Value;
}
r.EndEdit();
dTable.Rows.Add(r);
}
}
//setting the datasource, ok
dataGridView1.DataSource = dTable;
//Handlig a changed row or?
dTable.RowChanged += new DataRowChangeEventHandler(Row_Changed);
}
}
public static void Row_Changed(object sender, DataRowChangeEventArgs e)
{
}
}
P.S.: You should have this :/
using GemBox.Spreadsheet;
There are several ways to do this and several topics that regards this issue.
A quick fix is rebinding your dataSource to the dataGridView via a method attached to a 'refresh' button.
Use the following method, you can assign it to a on_click button event that you must create beforehand:
function bool refresh()
{
dataGridView1.DataSource = null;
dataGridView1.DataSource = dTable;
return true;
}
Alternatively, try looking around the forum, there are several similar topics that show different methods:
How to refresh or show immediately in datagridview after inserting?
How can I refresh c# dataGridView after update ?
I'm building an WinForms application which is going to be an adressbook. I'm stuck with a problem though. When I open the program and press on my load contacts button, it loads all that's written in the txt file. But if I create a new contact and press load again, the new contact doesn't show up. Is there any way to fix this?
Also, when I try to create new methods for example a Delete() method. It says "Items collection cannot be modified when the DataSource property is set." Any ideas why is crashes?
List<string> Load()
{
StreamReader read = new StreamReader(path);
string row = "";
while ((row = read.ReadLine()) != null)
{
adressbook.Add(row);
}
read.Close();
return adressbook; //Adressbook is my List<string> adressbook = new List<string> uptop.
}
private void button2_Click(object sender, EventArgs e)
{
List<string> list = Load();
listBox1.DataSource = list;
}
You have to set to null the DataSource before clearing and binding:
private void button2_Click(object sender, EventArgs e)
{
if(listBox1.DataSource != null)
{
listBox1.DataSource = null;
listBox1.Items.Clear();
}
List<string> list = Load();
listBox1.DataSource = list;
}
In your Load you must first clear the list
List<string> Load()
{
if (adressbook.Count != 0)
{
adressbook.Clear();
}
StreamReader read = new StreamReader(path);
string row = "";
while ((row = read.ReadLine()) != null)
{
adressbook.Add(row);
}
read.Close();
return adressbook; //Adressbook is my List<string> adressbook = new List<string> uptop.
}