问题描述
我正在使用DataGridView通过字符串包装器类,BindingSource和BindingList显示字符串值。
但是,在启动应用程序时,只有在单击行后才能看到这些值。我已经尝试查看所有可能的样式属性,以查看初始黑色的来源,但没有成功。
初始外观:
单击(有趣的颜色以尝试了解哪种样式可以做什么)或最小化和最大化窗口后:
表单代码(已经在此处尝试了一些变体,最终版本看起来不是这样):
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
,在网格下可见)。
解决方法
鉴于所描述的情况:
- 将空
List<class>
(很可能没有实现INotifyPropertyChanged
)添加到相同类型的BindingList中。 - 空的BindingList被设置为BindingSource的数据源。
- 将BindingSource(绑定到仍然为空的BindingList)设置为DataGridView的数据源。
某些新项目随后会添加到列表中。
在这种情况下,很容易验证BindingSource仅订阅该事件就不会收到任何ListChanged事件:该事件永远不会引发。
- 即使将
Bindinglist.Count
属性增加到添加的项目数,此计数也仅报告源List<class>
中包含的项目数,而不会通知更改。
DataGridView实际上可以显示新内容,但是底层的DataSource(由BindingSource生成的内部List)与原始源是 disconnected :当在DataGridView中选择“行”时,最常见的结果是之所以会出现IndexOutOfRangeException
,是因为我们试图从内部Dictionary访问非同步的Item,实际上是在索引-1
处访问Item。
可以使用几种方法来同步内部集合:
-
将新项直接添加到BindingList而不是源
List<class>
:BindingList将在链接的BindingSource中生成ListChanged
个事件,同步集合和源List<class>
仍然会更新。bindingList.Add(new StringValue("StringValue1")); bindingList.Add(new StringValue("StringValue2")); bindingList.Add(new StringValue("StringValue3"));
-
如果由于某些原因需要将新项目添加到原始
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);
-
我们可以将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>