c# - 以 BindingSource 作为 DataSource 的 DataGridview 仅在选择 Row 后才显示值
问题描述
我正在使用 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的 DataSource 。
- BindingSource(绑定到仍然为空的 BindingList)设置为 DataGridView 的 DataSource
一些新项目随后被添加到列表中。
在这种情况下,很容易验证 BindingSource 没有收到任何仅订阅事件的ListChanged事件:该事件永远不会引发。
- 即使该
Bindinglist.Count
属性增加到添加的项目数,此计数也仅报告 source 中包含的项目数,List<class>
不会通知更改。
DataGridView其实可以展示新的内容,但是底层的DataSource——BindingSource生成的内部List——和原来的源是断开的:当在DataGridView中选择了一个Row时,最常见的结果就是IndexOutOfRangeException
引发了an,因为我们' 正在尝试从内部字典访问非同步项目-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>
由于某种原因需要在原有的Item中添加新的Item,请在添加完新的Item之后调用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 将使用DataPropertyName
属性 if将其 Columns 绑定到数据源AutoGenerateColumns = false
,或者从源对象生成 Columns(s ) 属性名称,当AutoGenerateColumns = true
:BindingList bindingList = new BindingList<StringValue>(list); BindingSource bindingSource = new BindingSource(typeof(BindingList<StringValue>), null); dataGridView.DataSource = bindingSource;
将新的 Items 添加到 source
List<class>
后,将 BindingSource 的 DataSource 设置为 BindingList,导致内部集合重新同步:list.Add(new StringValue("StringValue1")); list.Add(new StringValue("StringValue2")); list.Add(new StringValue("StringValue3")); bindingSource.DataSource = bindingList;
推荐阅读
- android - AutocompleteDropdownlist 锚定到错误的 textView
- vba - 尝试基于多个键对数据进行排序时出现 VBA 错误 1004
- android - 如何使用意图通过蓝牙 BLE 发送双 [] 数组 - Android Studio (API 17)
- c - 如何在代码块上运行 Raspberry pi 的示例代码
- javascript - 将图像从数组迭代到类 javascript 中的类 img src
- c# - C# Ungreedy Regex 吞下换行符
- angular - 具有动态 arg 的货币管道
- javascript - 如何将现有的 Angular 2 TypeScript 应用程序迁移到 ReactJS?
- popup - 凤凰链接确认弹窗多次出现
- php - 如何在php的laravel中使用facebook/webdriver的ghost brawser