【问题标题】:ComboBox has DataSource set but is not displaying any itemsComboBox 已设置 DataSource 但未显示任何项目
【发布时间】:2021-11-09 20:21:43
【问题描述】:

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

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

属性DataSource在数据下载后检入调试模式时设置并保存MyObjects的列表。 属性项的计数始终为零。

我的代码如下:

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

displayBox.DataSource = ObjectBindingList;

DisplayMemberValueMember 在 GUI 设计器的组合框属性中设置。
controller 异步下载一些数据(MyDataObjects)异步。然后通过添加将ViewModel中的BindingList<MyObject> ObjectBindingList设置为下载的Objects。

【问题讨论】:

  • Debug。在上面显示的行上设置断点并检查集合ObjectBindingList。里面有物品吗?注意:如果您使用的是BindingSource 对象,则将绑定列表分配给绑定源的DataSource,而不是直接分配给组合框。
  • ObjectBindingListList<MyObject> 还是 BindingList<MyObject>?你提到了两者。 -- 在将项目添加到List(?) 后,您是否重置了绑定?
  • @Jimi 是一个BindingList,绑定列表被清空然后用ObjectBindingList.Add(downloadData[i].MyObject)函数填充。
  • @OlivierJacot-Descombes 不,因为当我绑定数据时下载尚未发生,所以 ObjectBindingList 已设置但没有项目( items.count = 0)。我想在下载完成后设置实际数据并相应地更新 ComboBox。
  • 如何添加数据?

标签: c# visual-studio winforms combobox datasource


【解决方案1】:

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

您可能看不到 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&lt;T&gt; 按预期工作,您必须添加项目

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

即,保留分配给数据源的原始BindingList&lt;MyObject&gt;


另请参阅:How can I improve performance of an AddRange method on a custom BindingList?


为避免该问题,建议将属性设为只读(使用 C# 9.0 的 Target-typed new expressions)。

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

【讨论】:

    【解决方案2】:

    似乎在尝试从与主窗体线程不同的线程更新 ComboBox 时,更新没有到达控件。 我现在在 Binding List 和控件之间使用 Invoke 方法和 BindingSource 对象。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多