从c#winform中的另一个表单更新gridview列值?

我有两个winforms MainFormGridForm

在MainForm.cs中

使用foreach逐个执行cmd rmdir命令

现在我想显示所有directory name列表及其status name是否为进程。

  foreach (var item in listBox1.Items) { System.Diagnostics.Process.Start("cmd.exe", "/c rmdir " + item); // want to show inside gridview in GridForm which folder is done - so uodate status as done var p = proc.ExitCode; string status; if (p == 1){ status = "fail"} else {status = "success"} // How to pass status text value to GridForm from here? I tried like // grid view bind which will pass items , what about status ? GridForm statusForm = new GridForm(listBox1.Items); GridForm.ShowDialog(); } 

问题是我无法将状态值传递给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; } 

网格没有状态

我的问题是在MainForm上有一个foreach,它逐个执行rmdir,现在当我点击MainForm上的执行按钮时,它将执行上面的foreach代码,并将打开另一个表格GridForm,它显示gridview有两列FolderName和Status我将得到来自ItemList的所有FoolderName和来自foreach的当前状态。

现在我怎样才能将它绑定到gridview?

您可以使用BindingSource让datagrid响应viewmodel实例中的更改。 您可以更新特定viewmodel的属性,BindingSource和数据绑定框架负责重新绘制和更新任何网格的行。

首先创建一个实现INotifyPropertyChanged的viewmodel类。 为简洁起见,我只实现了Status属性来引发属性更改事件。

 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 { get { return _status; } set { _status = value; Changed("Status"); } } public string Folder { get; set; } public event PropertyChangedEventHandler PropertyChanged; } 

确保在继续下一步之前编译项目。

在MainForm上,从Toolbox数据类别中拖放BindingSource 。 我命名了我的folders 。 将DataSource属性设置为新的项目数据源,并选择FolderStatusViewModel作为类型。
将datagrid的DataSource设置为folders bindingsource。
在主窗体中,load事件为每个文件夹创建一个集合(我更喜欢List),其中包含FolderStatusViewModel的实例

 private void MainForm_Load(object sender, EventArgs e) { var folders = new List(); foreach (var folder in Directory.EnumerateDirectories(@"c:\temp")) { folders.Add(new FolderStatusViewModel { Folder = folder }); } this.folders.DataSource = folders; } 

在你的GridFrom上添加一个DataGrid和BindingSource(我再次命名了这个文件夹 )。 将BindingSource设置为相同的项目数据源FolderStatusViewModel ,并将datagrid与绑定源连接。 GridForm的重载构造函数应该在Load事件中获取我们分配给BindingSource的对象:

 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; } } 

当您实例化GridForm时,您只需将mainform上BindingSource的DataSource属性值传递给GridForm的构造函数:

 // the grid form takes the DataSource from the folders BindingSource var grid = new GridForm(this.folders.DataSource); grid.Show(); // process each folder, making sure to get an instance of the // instances of the ViewModel, in this case by casting // the DataSource object back to the List foreach(var folderStatus in (List) 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 the instance of a FolderStatusViewModel // gets its Status property updated // all subscribers to the PropertyChanged event // get notified. BindingSource instances do subscribe to these // events, so that is why the magic happens. if (p.ExitCode > 0) { folderStatus.Status = String.Format("fail {0}", p.ExitCode); } else { folderStatus.Status = "succes"; } }; p.StartInfo = pi; p.Start(); } 

通过利用BindingSource,将数据绑定到任何这些实例的多个from将同时获得更新。 数据绑定framewoek将为您做繁重的工作。

如果您不想使用自己创建的ViewModel,但现有的DataTable会调整以上代码,如下所示:

form_load事件:

  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; } 

处理:

 // 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 } 

由于DataGrid现在无法知道哪些列存在,因此必须将这些列显式添加到每个数据网格设置每个列的DataPropertyName:

在网格中设置datacolumns