我有两个组合框envelopeList
和datasetList
。请考虑以下代码行:
envelopeList.DataBindings.Add("DataSource", datasetList, "SelectedValue");
预期的功能是在更改选择时将envelopeList.DataSource
更新为datasetList.SelectedValue
。但是,如果datasetList
为空,则抛出ArgumentException
说“附加信息:复杂数据绑定接受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
中的项目时数据源将被清空)。
为了完成这项工作,我必须在第一次填充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
绑定到包含IBindingList
个DatasetPresenter
个对象的DatasetPresenter
Areas
有一个属性IBindingList
,可返回envelopeList
,其中包含我想要datasetList.ValueMember = "Areas"
显示的对象。
我在进行绑定之前运行envelopeList.DataBindings.Add("DataSource", datasetList, "SelectedValue");
。
问题
即使datasetList
为空或取得类似结果,如何使AdvancedComboBox
正常工作?
我更喜欢在ComboBox的初始化期间执行的解决方案和/或我可以放在datasetList
类中的代码,以便它保持自包含。
奖励:为什么datasetList.SelectedValue
为空时不起作用?即使envelopeList.DataSource = null
返回null并且<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 10vw;
height: 10vw;
background-color: yellow;
border: solid black;
display: block
}
.cont {
position: relative;
display: block;
}
.cont>.box {
position: absolute;
display: block;
}
</style>
</head>
<body>
<div class="box">1</div>
<div class="cont">
<div class="box">2</div>
</div>
<div class="box">3</div>
</body>
</html>
也没问题。
答案 0 :(得分:0)
嗯,我找到了一个解决方案,但它并不漂亮。
我专门为此目的创建了这个类:
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.
这很难看,我仍然在寻找更好的解决方案。