以 BindingSource 作为 DataSource 的 DataGridview 仅在选择行后显示值
DataGridview with BindingSource as DataSource displays values only after selecting a Row
我使用 DataGridView 通过字符串包装器 class、BindingSource 和 BindingList 来显示字符串值。
但是,启动应用程序时,这些值仅在单击行后可见。我已经尝试查看所有可能的样式 属性 以查看初始黑色的来源,但没有成功。
初看:
单击(有趣的颜色以尝试了解哪种样式的作用)或最小化和最大化 window:
表单代码(已经在这里尝试了一些变体,最终版本不会像这样):
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;
}
我的问题是,如何让应用程序启动时已经显示网格中的值?如果有帮助,我可以 post 设计器代码,但是没有定义黑色(表单背景是 DarkGrey
,在网格下可见)。
鉴于所描述的场景:
- 将空
List<class>
(INotifyPropertyChanged
很可能未实现)添加到相同类型的 BindingList。
- 空BindingList is set as the DataSource of a BindingSource.
- BindingSource(绑定到仍为空的 BindingList)被设置为 DataGridView 的 DataSource
之后列表中添加了一些新项目。
在这种情况下,验证 BindingSource 没有收到任何 ListChanged 订阅事件的事件很简单:永远不会引发事件。
- 即使
Bindinglist.Count
属性 增加到添加的项目数,此计数仅报告源 List<class>
中包含的项目数,而不会通知更改。
DataGridView 实际上可以显示新的内容,但是底层的 DataSource——BindingSource 生成的内部 List——与原始源 断开连接:当在 DataGridView 中选择一个 Row 时,最常见的结果是引发 IndexOutOfRangeException
,因为我们试图从内部字典访问非同步项目,访问索引 -1
处的项目,在实践中。
可以使用多种方法来同步内部集合:
将新项目直接添加到 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>
需要添加新的Items,由于某些原因,在添加新的Items后调用BindingList.ResetBinding()
or the 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);
与其直接使用BindingList<class>
对象作为BindingSource的DataSource,我们可以将DataSource设置为相应的Type,这样DataGridView会将其Columns绑定到数据源使用DataPropertyName
属性,如果 AutoGenerateColumns = false
,或者从源对象属性名称生成列,当 AutoGenerateColumns = true
:
BindingList bindingList = new BindingList<StringValue>(list);
BindingSource bindingSource = new BindingSource(typeof(BindingList<StringValue>), null);
dataGridView.DataSource = bindingSource;
新的Item添加到源List<class>
后,设置BindingSource的DataSource为BindingList,导致内部集合re-synchronize:
list.Add(new StringValue("StringValue1"));
list.Add(new StringValue("StringValue2"));
list.Add(new StringValue("StringValue3"));
bindingSource.DataSource = bindingList;
我使用 DataGridView 通过字符串包装器 class、BindingSource 和 BindingList 来显示字符串值。
但是,启动应用程序时,这些值仅在单击行后可见。我已经尝试查看所有可能的样式 属性 以查看初始黑色的来源,但没有成功。
初看:
单击(有趣的颜色以尝试了解哪种样式的作用)或最小化和最大化 window:
表单代码(已经在这里尝试了一些变体,最终版本不会像这样):
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;
}
我的问题是,如何让应用程序启动时已经显示网格中的值?如果有帮助,我可以 post 设计器代码,但是没有定义黑色(表单背景是 DarkGrey
,在网格下可见)。
鉴于所描述的场景:
- 将空
List<class>
(INotifyPropertyChanged
很可能未实现)添加到相同类型的 BindingList。 - 空BindingList is set as the DataSource of a BindingSource.
- BindingSource(绑定到仍为空的 BindingList)被设置为 DataGridView 的 DataSource
之后列表中添加了一些新项目。
在这种情况下,验证 BindingSource 没有收到任何 ListChanged 订阅事件的事件很简单:永远不会引发事件。
- 即使
Bindinglist.Count
属性 增加到添加的项目数,此计数仅报告源List<class>
中包含的项目数,而不会通知更改。
DataGridView 实际上可以显示新的内容,但是底层的 DataSource——BindingSource 生成的内部 List——与原始源 断开连接:当在 DataGridView 中选择一个 Row 时,最常见的结果是引发IndexOutOfRangeException
,因为我们试图从内部字典访问非同步项目,访问索引-1
处的项目,在实践中。
可以使用多种方法来同步内部集合:
将新项目直接添加到 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>
需要添加新的Items,由于某些原因,在添加新的Items后调用BindingList.ResetBinding()
or theBindingSource.ResetBinding(false)
方法;这将生成ListChanged
事件,结果将执行同步:list.Add(new StringValue("StringValue1")); list.Add(new StringValue("StringValue2")); list.Add(new StringValue("StringValue3")); bindingList.ResetBindings(); // Or... // bindingSource.ResetBinding(false);
与其直接使用
BindingList<class>
对象作为BindingSource的DataSource,我们可以将DataSource设置为相应的Type,这样DataGridView会将其Columns绑定到数据源使用DataPropertyName
属性,如果AutoGenerateColumns = false
,或者从源对象属性名称生成列,当AutoGenerateColumns = true
:BindingList bindingList = new BindingList<StringValue>(list); BindingSource bindingSource = new BindingSource(typeof(BindingList<StringValue>), null); dataGridView.DataSource = bindingSource;
新的Item添加到源
List<class>
后,设置BindingSource的DataSource为BindingList,导致内部集合re-synchronize:list.Add(new StringValue("StringValue1")); list.Add(new StringValue("StringValue2")); list.Add(new StringValue("StringValue3")); bindingSource.DataSource = bindingList;