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

时间:2015-10-03 07:32:50

标签: c# winforms gridview

我有两个winforms MainFormGridForm

MainForm.cs中的

使用cmd rmdir

逐个执行foreach命令

现在,我想要显示所有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;
   }

grid with no status

我的问题是关于MainForm有一个foreach 现在当我点击执行按钮时,它逐个执行rmdir MainForm它将执行上面的foreach代码,并将打开 另一种形式GridForm,它显示了带有两列FolderName的gridview 和状态我将从ItemList和当前状态获取所有FoolderName 来自foreach。

现在如何将其绑定到gridview?

1 个答案:

答案 0 :(得分:4)

您可以使用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上,从工具箱数据类别中拖放BindingSource。我命名为folders。将DataSource属性设置为新项目数据源,然后选择FolderStatusViewModel作为类型 将数据网格的DataSource设置为folders绑定源 在主窗体中,load事件为每个文件夹创建一个集合(我更喜欢List),其实例为FolderStatusViewModel

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

在GridFrom上添加一个DataGrid和BindingSource(我再次命名了一个文件夹)。将BindingSource设置为相同的项目数据源FolderStatusViewModel,并使用绑定源连接数据网格。 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<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 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现在无法知道哪些列存在,您必须将这些列显式添加到每个数据网格 AND 设置每列的DataPropertyName:

set datacolumns in grid