我有两个winforms MainForm
和GridForm
使用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;
}
我的问题是关于MainForm有一个foreach 现在当我点击执行按钮时,它逐个执行rmdir MainForm它将执行上面的foreach代码,并将打开 另一种形式GridForm,它显示了带有两列FolderName的gridview 和状态我将从ItemList和当前状态获取所有FoolderName 来自foreach。
现在如何将其绑定到gridview?
答案 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: