我怎样才能将这些值作为参考传递?

时间:2013-12-02 15:26:06

标签: c# .net winforms

我有一个填充了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本身传递给自己,而不是从行构建的对象列表是不好的做法?

2 个答案:

答案 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);
}
}