Bindingsource不能是自己的数据源

时间:2015-07-08 08:48:21

标签: c# datagridview uri bindingsource bindinglist

当我从BindingList更新datagriview时,偶尔会收到错误“Bindingsource不能成为自己的数据源”。在涉及抛出错误时,我没有任何押韵或理由。如果有人有一些见解,我们非常感激。

enter image description here

        dgv_Items.DataSource = null;
        dgv_Items.DataSource = new BindingSource(Item.ObjectsItem.OrderBy(x => x.Quality), null);

        foreach (DataGridViewRow row in dgv_Items.Rows)
        {
            try
            {
                if (row.Cells[5].Value != null)
                {
                    var cell = row.Cells[5].Value;
                    if (Uri.IsWellFormedUriString(cell.ToString(), UriKind.Absolute))
                    {
                        DataGridViewLinkCell linkCell = new DataGridViewLinkCell
                        {
                            LinkColor = Color.Blue,
                            Value = cell
                        };
                        row.Cells[5] = linkCell;
                    }
                }
            }
            catch (Exception ex)
            {
                Main.Log("Error: " + ex);
            }
        }

1 个答案:

答案 0 :(得分:1)

bindingsource用于将数据绑定到显示的数据。在您的情况下,显示的数据是数据网格视图。

如果您决定使用绑定源作为DataGridView的数据源,则不应再以编程方式处理DataGridView。因为您告诉DataGridView它的DataSource将是您的BindingSource,所以您的程序应该只通过更改DataSource中的数据来更改数据。一旦更改,DataGridview和BindingSource将注意相应的显示项目更新。

同样,如果操作员更改显示的项目,DataGridView和BindingSource将注意相应的对象更新。

  

一旦设置了DataGridView的DataSource,就不应该以编程方式更改DataGridView,而是更改DataSource中的数据。

您希望显示URI字符串,问题是如果它发生更改,则没有人会收到有关这些更改的通知,因此没有人可以对更改做出反应。原因是因为类字符串没有实现接口INotifyPropertyChanged

所以我们必须创建一个要显示的URI字符串类。

public class MyDisplayableUriString
{
   public string UriString {get; set;}
   ... // if desired other properties
}

我们希望表单显示MyDisplayableUriString列表:

  • 创建新的Windows窗体应用程序
  • 使用工具箱添加BindingSource
  • BindingSource属性DataSource = MyDisplayableUriString
  • 使用工具箱添加DataGridView
  • DataGridView属性:DataSource = BindingSource1

您应该会在DataGridView中看到MyDisplayableUriString的字段。

  • 使用属性窗口来确定表单加载时的事件处理程序

在此事件处理程序中,使用多个可显示的URi字符串填充BindingSource:

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 0; i < 10; ++i)
    {
        MyDisplayableUriString uriItem = new MyDisplayableUriString()
        {
            Uri = "URI " + i.ToString()
        };
        this.bindingSource1.Add(uriItem);
    }
}

如果您运行该程序,您应该看到该表填充了创建的URI项。

现在让我们更改其中一项:

  • 添加按钮并为按钮单击创建处理程序:

    private void button1_Click(object sender,EventArgs e) {     MyDisplayableUriString uriItem =(MyDisplayableUriString)this.bindingSource1 [0];     uriItem.UriString =“John”; }

现在,如果您运行该程序并单击该按钮,则名称不会更新。

原因是您的类没有实现INotifyPropertyChanged。因此,当更改uri项目时,不会通知bindingsource。因此DataGridView不会更新。

幸运的是,StackOverflow有一篇关于正确实现的文章: Implementing INotifyPropertyChanged

代码如下:

public event PropertyChangedEventHandler PropertyChanged;

private string uriName = null;
public string UriName
{
    get { return this.uriName; }
    set { this.SetField(ref this.uriName, value); }
}

protected void SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        RaiseEventPropertyChanged(propertyName);
    }
}

private void RaiseEventPropertyChanged(string propertyName)
{
    var tmpEvent = this.PropertyChanged;
    if (tmpEvent != null)
    {
        tmpEvent(this, new PropertyChangedEventArgs(propertyName));
    }
}

现在,只要程序更改了绑定源中的对象,显示就会自动更新,如果操作员更改了显示,则会更新bindingsource中的项目,并通过事件通知您的程序