只有将BindingSource作为DataSource的DataGridview才显示值

问题描述

我正在使用DataGridView通过字符串包装器类,BindingSource和BindingList显示字符串值。
但是,在启动应用程序时,只有在单击行后才能看到这些值。我已经尝试查看所有可能的样式属性,以查看初始黑色的来源,但没有成功。

初始外观:

enter image description here

单击(有趣的颜色以尝试了解哪种样式可以做什么)或最小化和最大化窗口后:

enter image description here

表单代码(已经在此处尝试了一些变体,最终版本看起来不是这样):

private BindingSource dataSource;
private BindingList<StringValue> bindingList;
private List<StringValue> list = new List<StringValue>();

public MainForm()
{
    InitializeComponent();

    GrdCodes.AutoGenerateColumns = false;

    bindingList = new BindingList<StringValue>(list);
    dataSource = new BindingSource(bindingList,null);
    GrdCodes.DataSource = dataSource;

    // Load += MainForm_Load;
    x();
}

//private void MainForm_Load(object sender,EventArgs e)
//{
//    GrdSupiCodes.AutoGenerateColumns = false;

//    bindingList = new BindingList<StringValue>(list);
//    dataSource  = new BindingSource(bindingList,null);
//    GrdSupiCodes.DataSource = dataSource;
//}

private void x()
{
    list.Add(new StringValue("AAAAAAAAAAAA"));
    list.Add(new StringValue("BBBBBBBBBBBB"));
    list.Add(new StringValue("CCCCCCCCCCCC"));

    // none of the below work:
    GrdCodes.ResetBindings();

    // GrdCodes.Update();
    // GrdCodes.Refresh();

    // GrdCodes.DataSource = null;
    // GrdCodes.DataSource = dataSource;
}

我的问题是,如何使应用程序启动时已经在网格中显示值?如果有帮助,我可以发布设计器代码,但是没有地方定义黑色(表单背景为DarkGrey,在网格下可见)。

解决方法

鉴于所描述的情况:

  1. 将空List<class>(很可能没有实现INotifyPropertyChanged)添加到相同类型的BindingList中。
  2. 空的BindingList被设置为BindingSource的数据源。
  3. 将BindingSource(绑定到仍然为空的BindingList)设置为DataGridView的数据源。

某些新项目随后会添加到列表中。
在这种情况下,很容易验证BindingSource仅订阅该事件就不会收到任何ListChanged事件:该事件永远不会引发。

  • 即使将Bindinglist.Count属性增加到添加的项目数,此计数也仅报告源List<class>中包含的项目数,而不会通知更改。
    DataGridView实际上可以显示新内容,但是底层的DataSource(由BindingSource生成的内部List)与原始源是 disconnected :当在DataGridView中选择“行”时,最常见的结果是之所以会出现 IndexOutOfRangeException ,是因为我们试图从内部Dictionary访问非同步的Item,实际上是在索引-1处访问Item。

可以使用几种方法来同步内部集合:

  1. 将新项直接添加到BindingList而不是源List<class>:BindingList将在链接的BindingSource中生成ListChanged个事件,同步集合和源List<class>仍然会更新。

     bindingList.Add(new StringValue("StringValue1"));
     bindingList.Add(new StringValue("StringValue2"));
     bindingList.Add(new StringValue("StringValue3"));
    
  2. 如果由于某些原因需要将新项目添加到原始List<class>中,请在添加新项目后调用BindingList.ResetBinding()BindingSource.ResetBinding(false)方法;这将生成ListChanged事件,并因此执行同步:

     list.Add(new StringValue("StringValue1"));
     list.Add(new StringValue("StringValue2"));
     list.Add(new StringValue("StringValue3"));
     bindingList.ResetBindings();
     // Or...
     // bindingSource.ResetBinding(false);
    
  3. 我们可以将DataSource设置为相应的Type,而不是直接使用BindingList<class>对象作为BindingSource的DataSource,因此DataGridView将使用{{ 1}}属性(如果为DataPropertyName,或在AutoGenerateColumns = false时从源对象的属性名称生成列:

    AutoGenerateColumns = true

    在将新项添加到源 BindingList bindingList = new BindingList<StringValue>(list); BindingSource bindingSource = new BindingSource(typeof(BindingList<StringValue>),null); dataGridView.DataSource = bindingSource; 之后,将BindingSource的DataSource设置为BindingList,从而使内部集合重新同步:

    List<class>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...