I’ve got a class that represents an XML file to be “processed”. I’ve created a BindingList of these objects and bound it to a DataGridView so the user (i.e. me) can “control” things a bit and “see” what’s happening. By default, the constructor assumes all files in the list will be “processed”:
public class InputFileInfo : INotifyPropertyChanged
{
private bool processThisFile;
public bool Process
{
get { return processThisFile; }
set
{
processThisFile = value;
this.NotifyPropertyChanged("Process");
}
}
public string FileName { get; set; }
public int Rows { get; set; }
public string Message { get; set; }
// constructor
public InputFileInfo(string fName)
{
Process = true;
FileName = fName;
Rows = 0;
Message = String.Empty;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
The first column of the DGV called “Process” might become unchecked in which case I want to skip that file (i.e. row) and continue with the next. The last 2 columns of the DGV are intended to display the number of output Rows that were emitted out of the processed XML file and a place to put some sort of Message (such as “OK” or “error text”).
In short, I want the DataGridView to be the visual representation of the process, echoing results in 2 little columns and allowing the user to skip a row by unchecking it.
Clicking on a button starts the processing of the files in the DGV. Here is what I have sketched so far (seems to work but the DGV does not reflect changes made in fileInfo.Rows and fileInfo.Message):
—– EDIT-UPDATE: per David Hall’s suggestion, looping thru the BindingList (_filesToParse) is a good fix to this problem (working code follows):
private void btnProcess_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream("output-file.txt", FileMode.Create);
StreamWriter writer = new StreamWriter(fs);
OutputColumnNamesAsFirstLine(writer);
foreach (InputFileInfo fileInfo in _filesToParse)
{
if (fileInfo.Process == true)
{
try
{
fileInfo.Rows = processFile(writer, fileInfo.FileName);
}
catch (Exception ex)
{
log.Warn("Error processing DataGridView:\r\n", ex);
}
}
else
{
fileInfo.Rows = 0;
fileInfo.Message = "skipped";
}
}
writer.Dispose();
fs.Dispose();
MessageBox.Show("All selected files have been processed.");
}
What would be the best approach?
- Loop through the BindingList ?
- Loop through the DataGridView ?
I think what I need is “two-way” binding but I maybe not? Am I close?
—————–E D I T (UPDATE)—————-
Yes, the XML files already exist. Here is how that part works:
private void initializeFileList(string rootFolder) // populate grid with .xml filenames to be processed
{
String root = rootFolder;
var result = Directory.GetFiles(root, "*.xml", SearchOption.AllDirectories)
.Select(name => new InputFileInfo(name))
.ToList();
_filesToParse = new BindingList<InputFileInfo>(result.ToList());
dataGridView1.DataSource = _filesToParse;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
btnProcess.Visible = true;
David Hall’s comment(s) gave me enough confidence to go in this direction:
I took a stab at this code and posted it above by EDITing the original post. The code works but the DGV does not reflect it properly.
So, this question morphed into a different question about how to achieve 2-way binding for a datagridview which I opened in (this new thread):How to use a static utility method for property setters in a utility class