update gridview column values from another form in c# winform? -
i have 2 winforms mainform
, gridform
in mainform.cs
executing cmd rmdir
command 1 one using foreach
now want show list of directory name
, status name
wether process or not.
foreach (var item in listbox1.items) { system.diagnostics.process.start("cmd.exe", "/c rmdir " + item); // want show inside gridview in gridform folder done - uodate status done var p = proc.exitcode; string status; if (p == 1){ status = "fail"} else {status = "success"} // how pass status text value gridform here? tried // grid view bind pass items , status ? gridform statusform = new gridform(listbox1.items); gridform.showdialog(); }
problem i'm unable pass status value gridform
gridform.cs private void gridform_load(object sender, eventargs e) { datatable dt = new datatable(); dt.columns.add("name"); foreach (string items in _itemlist) { datarow row = dt.newrow(); dt.rows.add(items); } this.statusgridview.datasource = dt; }
my question on mainform there foreach execute rmdir 1 one , when click on execute button on mainform execute above foreach code , open form gridform shows gridview 2 column foldername , status fooldername itemlist , current status foreach .
now how can bind gridview?
you can use bindingsource have datagrid respond changes in instances of viewmodel. can update property of specific viewmodel , bindingsource , databinding framework takes care of repainting , updating rows of grid.
first create viewmodel class implements inotifypropertychanged. brevity implemented status property raise property changed event.
class folderstatusviewmodel:inotifypropertychanged { string _status; string _folder; private void changed(string propertyname) { var changed = propertychanged; if (changed != null) { changed.invoke(this, new propertychangedeventargs(propertyname)); } } public string status { { return _status; } set { _status = value; changed("status"); } } public string folder { get; set; } public event propertychangedeventhandler propertychanged; }
make sure compile project before continuing next step.
on mainform drag , drop bindingsource
toolbox data category. named mine folders
. set datasource
property new project datasource , select folderstatusviewmodel
type.
set datasource
of datagrid folders
bindingsource.
in main form load event create collection (i prefer list) instance of folderstatusviewmodel
each folder
private void mainform_load(object sender, eventargs e) { var folders = new list<folderstatusviewmodel>(); foreach (var folder in directory.enumeratedirectories(@"c:\temp")) { folders.add(new folderstatusviewmodel { folder = folder }); } this.folders.datasource = folders; }
on gridfrom add datagrid , bindingsource (i named 1 folders again). set bindingsource same project datasource folderstatusviewmodel
, hookup datagrid binding source. overloaded constructor of gridform should take object assign bindingsource in load event:
public partial class gridform : form { public gridform() { initializecomponent(); } object source = null; public gridform(object datasource):this() { this.source = datasource; } private void gridform_load(object sender, eventargs e) { this.folders.datasource = source; } }
when instantiate gridform can pass value of datasource property of bindingsource on mainform constructor of gridform:
// grid form takes datasource folders bindingsource var grid = new gridform(this.folders.datasource); grid.show(); // process each folder, making sure instance of // instances of viewmodel, in case casting // datasource object list foreach(var folderstatus in (list<folderstatusviewmodel>) this.folders.datasource) { var pi = new processstartinfo(); pi.filename ="cmd.exe"; pi.arguments ="/c dir /s *.*"; pi.createnowindow = true; var p = new process(); p.enableraisingevents = true; p.exited += (s,ee) => { // here instance of folderstatusviewmodel // gets status property updated // subscribers propertychanged event // notified. bindingsource instances subscribe these // events, why magic happens. if (p.exitcode > 0) { folderstatus.status = string.format("fail {0}", p.exitcode); } else { folderstatus.status = "succes"; } }; p.startinfo = pi; p.start(); }
by leveraging bindingsource multiple froms databound of these instances updates simultaneously. databinding framewoek heavy lifting you.
if don't want use self created viewmodel existing datatable adapt above code follows:
the form_load event:
private void mainform_load(object sender, eventargs e) { var folders = new datatable(); folders.columns.add("status"); folders.columns.add("folder"); foreach (var folder in directory.enumeratedirectories(@"c:\temp")) { var row = folders.newrow(); folders.rows.add(row); row["folder"] = folder; } this.folders.datasource = folders; }
the processing:
// other code omitted foreach(datarow folderstatus in ((datatable) this.folders.datasource).rows) { // other code omitted p.exited += (s,ee) => { if (p.exitcode > 0) { folderstatus["status"] = string.format("fail {0}", p.exitcode); } else { folderstatus["status"] = "succes"; } }; // other code omitted }
as datagrid has no way know columns exist have explicitly add each datagrid and set datapropertyname of each column:
Comments
Post a Comment