【问题标题】:update gridview column values from another form in c# winform?从 c# winform 中的另一个表单更新 gridview 列值?
【发布时间】:2015-10-03 07:32:50
【问题描述】:

我有两个 winform 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 显示带有两列 FolderName 的 gridview 和状态我将从项目列表和当前状态中获取所有文件夹名称 来自 foreach 。

现在如何将它绑定到gridview?

【问题讨论】:

  • 为什么要在主窗体中启动两个进程?第二次调用 Process.Start 时使用的 ProcessStartInfo 的内容是什么?
  • 对不起,它是一个虚拟代码,只有一个进程。问题是我如何将连续值从一种形式传递到另一种形式?这样我就可以在 gridview 其他列中更新状态成功/失败
  • 不清楚 foreach 是否重命名了多个目录,并且您希望在重命名操作执行时将此操作的结果一一传递给已加载的 GridForm,或者您是否要传递所有重命名导致一批尚未加载的 GrdiForm
  • 我知道我出错了。我的问题是在 MainForm 上,有一个 foreach 一个一个地执行 rmdir ,现在当我单击 MainForm 上的执行按钮时,它将在 foreach 代码上方执行,这将打开另一个表单 GridForm ,它显示带有两列 FolderName 和 @987654333 的 gridview @我将从 ItemList 中获取所有 FoolderName 并从 foreach 中获取 Current Status 。现在我怎样才能将它绑定到gridview?
  • 更新感谢指出。

标签: c# winforms gridview


【解决方案1】:

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

首先创建一个实现INotifyPropertyChanged 的视图模型类。为简洁起见,我只实现了 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 作为类型。
将数据网格的DataSource 设置为folders 绑定源。
在您的主表单加载事件中,为每个文件夹创建一个带有 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(我再次将其命名为 folders)。将 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 时,您可以简单地将主窗体上 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,数据绑定到任何这些实例的多个 froms 将同时获得更新。数据绑定框架将为您完成繁重的工作。

如果你不想使用自己创建的 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:

【讨论】:

    猜你喜欢
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2021-10-28
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多