ComboBox设置了数据源,但不显示任何项



我有一个窗体与ComboBox DisplayBox。在我的ViewModel,我现在有一个属性BindingList<MyObject> ObjectBindingList,我想绑定到DisplayBox

当我加载表单时,DisplayBox不显示任何文本。

设置属性DataSource,并在数据下载后的调试模式检查时保存MyObjects的列表。属性项的计数总是为0。

我的代码工作如下:

在启动时,我将表单类中的数据绑定设置为仍然为空的列表objectindinglist。

displayBox.DataSource = ObjectBindingList;

DisplayMemberValueMember是在GUI设计器的ComboBox属性中设置的。
controller异步下载一些数据(MyDataObjects)。然后通过添加下载的对象来设置ViewModel中的BindingList<MyObject> ObjectBindingList

由于我没有看到所有相关代码,所以我只能假设发生了什么。

可能,您没有在ComboBox中看到数据,因为您在加载数据时创建了一个新的BindingList。但是ComboBox仍然附属于旧的空列表。

使用一个空列表初始化数据源,如下所示:

// Property
BindingList<MyObject> ObjectBindingList { get; set; }

其他地方的

// Initializes data source with an empty `BindingList<MyObject>`.
ObjectBindingList = new BindingList<MyObject>();
displayBox.DataSource = ObjectBindingList;

之后,加载数据并替换列表:

ObjectBindingList  = LoadData();

现在,您有两个列表:分配给displayBox.DataSource的初始空列表和分配给属性ObjectBindingList的新填充列表。注意,displayBox.DataSource没有对属性本身的引用,因此它看不到属性的新值。

要使BindingList<T>按预期工作,必须添加带有

的项
var records = LoadData();
foreach (var data in records) {
ObjectBindingList.Add(data);
}

。,保留原BindingList<MyObject>分配给数据源。


参见:如何提高自定义BindingList上adrange方法的性能?


为了避免这个问题,我建议将属性设置为只读(使用c# 9.0的目标类型的new表达式)。

BindingList<MyObject> ObjectBindingList { get; } = new();

当尝试从不同的线程而不是主窗体线程更新ComboBox时,更新没有到达控件。我现在在绑定列表和控件之间使用Invoke方法和BindingSource对象。

private void SetBindingSourceDataSource( BindingList<MyObject> myBindingList)
{
if (InvokeRequired)
{
Invoke(new Action<BindingList<MyObject>>(SetBindingSourceDataSource),  myBindingList);
}
else {
this.BindingSource.DataSource = myBindingList;
}
}

我特别在每次调用下载函数结束时触发的PropertyChanged事件上调用上述函数。

最新更新