我有一个填充了List<VersionedFile>
的网格。用户可以选择任意数量的行,并让应用程序对它们执行某种SVN功能;添加,提交,删除等。
目前,在用户修改文件后,列表不会立即反映状态更改。他们需要重新查询目录,这可能需要一段时间。我正在努力修复代码,以便在操作成功后立即更新UI。
所以我有这个代码迭代网格中的选定行,并将每一行作为VersionedFile
对象返回并将其抛出到列表中。然后我迭代这个列表,执行Add / Remove / action并将该迭代的Status
属性设置为适当的值。但是,UI不会改变。
UI:
private void btnAdd_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;
var vfiles = GetVFiles();
_presenter.SvnAdd(vfiles);
Cursor = DefaultCursor;
}
private List<VersionedFile> GetVFiles()
{
var files = new List<VersionedFile>();
foreach (var key in gdcSVNDefaultView.GetSelectedRows())
files.Add((VersionedFile)gdcSVNDefaultView.GetRow(key));
return files;
}
主讲人:
public void SvnAdd(List<VersionedFile> files)
{
var sb = new StringBuilder();
var numExceptions = 0;
foreach (var file in files)
{
try
{
_helper.SvnAdd(file.Path);
file.Status = SvnStatus.Added;
}
catch (Exception ex)
{
LogException(ex);
if (numExceptions < 10)
sb.AppendLine(file.Path);
numExceptions++;
}
}
ShowResult("Added", sb.ToString(), numExceptions, files.Count);
}
代码编译并运行完美。 vfiles
中包含适当的数据。但是在我手动刷新网格之前,我的UI才会更新。我假设沿着SvnAdd的某个地方只是接收一个值相等的对象,而不是对网格中该行的实际数据的引用。
关于如何解决此问题的任何想法?将SvnAdd本身传递给自己,而不是从行构建的对象列表是不好的做法?
答案 0 :(得分:1)
不是在GetVFiles
中构建新列表,而是返回网格的实际DataSource
,以便直接修改:
private List<VersionedFile> GetVFiles()
{
return (List<VersionedFile>)gdcSVNDefaultView.DataSource;
}
答案 1 :(得分:0)
这可以解决您在单个线程上更新数据的问题。更新数据后,将通知返回到UI线程上的网格。这是通过BindingSource完成的。首先,创建一个继承BindingSource的类,并将其用作网格的数据源。将任何DataTable设置为BindingSource的数据源。
在BindingSource类中添加:
protected override void OnListChanged(ListChangedEventArgs e)
{
var control = Form.ActiveForm;
if (control != null && control.InvokeRequired)
control.Invoke(new Action<ListChangedEventArgs>(OnListChanged), e);
else
{
base.OnListChanged(e);
}
}