【问题标题】:Binding DataSource of one ComboBox to SelectedValue of another将一个 ComboBox 的 DataSource 绑定到另一个 ComboBox 的 SelectedValue
【发布时间】:2018-03-07 13:33:51
【问题描述】:

我有两个组合框 envelopeListdatasetList。考虑以下代码行:

envelopeList.DataBindings.Add("DataSource", datasetList, "SelectedValue");

预期功能是在选择更改时将envelopeList.DataSource 更新为datasetList.SelectedValue。但是,如果 datasetList 为空,则会引发 ArgumentException 表示“附加信息:复杂 DataBinding 接受 IList 或 IListSource 作为数据源。”

我不明白为什么会这样。当datasetList 为空时,datasetList.SelectedValue 返回 null,envelopeList.DataSource = null 不抛出任何异常。这也不会引发任何异常:envelopeList.DataSource = datasetList.SelectedValue;,也不会引发任何异常:envelopeList.DataSource = new BindingSource(datasetList, "SelectedValue");,即使datasetList 为空。

datasetList 至少有一项按预期工作之后进行绑定,直到它变为空,在这种情况下envelopeList.DataSource 不会更新。 DataSourceChanged 事件甚至没有被触发。 (尽管在我的情况下,用户注意到了,因为当 datasetList 中的项目被删除时,DataSource 将被清空)。

为了完成这项工作,我必须在第一次填充 datasetList 后执行以下代码:

if(doonce && !(doonce = false))
    envelopeList.DataBindings.Add("DataSource", datasetList, "SelectedValue");

这是一种非常丑陋的方法,我更希望能够在初始化期间这样做。


一些潜在的重要信息。

这两个 ComboBox 实际上都是我自己的继承类型AdvancedComboBox。这是其中的相关功能:

public class AdvancedComboBox : ComboBox, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected override void OnSelectedValueChanged(EventArgs e)
    {
        base.OnSelectedValueChanged(e);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedValue")); //I don't know why, but it works even if I remove this line.
    }
}

PropertyChanged 事件我还有其他用途,即使 SelectedValue 属性显然不需要它。)

datasetList.DataSource 绑定到一个包含DatasetPresenter 对象的IBindingList
DatasetPresenter 有一个属性Areas,它返回一个IBindingList,其中包含我希望envelopeList 显示的对象。 我在绑定之前运行datasetList.ValueMember = "Areas"


问题

即使datasetList 为空,我如何使envelopeList.DataBindings.Add("DataSource", datasetList, "SelectedValue"); 工作或获得类似的结果?
我更喜欢只需要在 ComboBoxes 初始化期间执行的解决方案和/或我可以放入 AdvancedComboBox 类中的代码,以便它保持自包含。

奖励:为什么当datasetList 为空时它不起作用?即使 datasetList.SelectedValue 返回 null 并且 envelopeList.DataSource = null 也可以。

【问题讨论】:

    标签: c# winforms data-binding


    【解决方案1】:

    嗯,我找到了一个解决方案,但它并不漂亮。

    我专门为此目的创建了这个类:

    private class PlaceHolder
    {
        public string Name { get; }//This property is the DisplayMember of both ComboBoxes.
        public List<PlaceHolder> Areas { get { return new List<PlaceHolder>(0); } }//This property is the ValueMember of datasetList.
    }
    

    在初始化期间我运行这段代码。

    datasetList.DataSource = new List<PlaceHolder>() { new PlaceHolder() };
    envelopeList.DataBindings.Add("DataSource", datasetList, "SelectedValue");
    datasetList.DataSource = myController.Datasets;//This is the intended data source.
    

    这很丑,我仍在寻找更好的解决方案。

    【讨论】:

      猜你喜欢
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 2011-04-17
      • 2021-07-07
      • 2010-09-30
      • 1970-01-01
      相关资源
      最近更新 更多