我正在编写Windows应用程序并使用Listbox控件。我正在使用Visual Studio C#2008 Express Edition进行开发。
我有一个看起来像这样的数据对象
public class RootObject
{
public List<SubObject> MySubObjects{ get; set;}
}
我的表单上有一个ListBox,还有一个属性“MyRootObject”,它显然拥有一个RootObject。初始化控件时,我设置:
_listBox.DataSource = MyRootObject.MySubObjects;
现在,当表单加载时,我调试并看到正确设置了DataSource。但没有显示任何内容。我已经覆盖了SubObject的ToString()方法,甚至没有被调用。我尝试将_listBox.DisplayMember设置为SubObject的属性,只是为了查看是否存在某些问题,但仍然没有。我在设置DataSource后尝试调用_listBox.Update()和_listBox.Refresh(),但仍然没有爱。 DataSource拥有所有数据......它只是拒绝显示它。
因此,在调试时,我想知道WTF,我决定只做
_listBox.DataSource = new List<SubObject>{ new SubObject(), new SubObject() };
果然,这很有效,我看到列表框中列出了两件事。
那么,真的很好奇,我决定尝试复制对象列表并将其放入列表框中,如下所示:
_listBox.DataSource = MyRootObject.MySubObjects.ToArray();
这个有效!现在这是解决我的问题的方法......但是非常讨厌。有谁知道为什么我需要基本上复制像这样的对象列表才能使它工作,而不是只设置_listBox.DataSource = MyRootObject.MySubObjects; ?同样,DataSource在设置之后以任何一种方式拥有所有正确的数据...它只是在复制数据时,它实际显示,而当它不复制时,它不会显示。
答案 0 :(得分:5)
((CurrencyManager)_listBox.BindingContext[_listBox.DataSource]).Refresh();
Sux0r我知道,但这很有效。 (最初找到答案here)
答案 1 :(得分:1)
在我的脑海中,这是因为ListBox.DataSource
属性必须包含实现IList
接口的内容。您的通用List<SubObject>
未实现IList
;它实现IList<T>
(在System.Collections.Generic
命名空间中)。另一方面,Array
个对象继承自IList
,因此通过这种对象传递数据是有效的。
您可以尝试从Enumerator
对象中提取IList
(也会实现List<SubObject>
)并将其插入。如果有效,那么我所描述的问题就是您的问题问题。如果没有,那我就是在说话了。
如果这确实是问题,我很惊讶在一个不受支持的对象中推迟不会引发异常。
答案 2 :(得分:1)
到目前为止我知道,无论何时你想要将集合设置为
[ComboBox,ListBox].DataSource
您必须设置DisplayMember和ValueMember。 DisplayMember和ValueMember填充了分配给listbox / combobox的集合中Class的属性名称。实施例
//Populate the data
RootObject root = new RootObject();
root.MySubObjects.Add(new SubObject("1", "data 1"));
root.MySubObjects.Add(new SubObject("2", "data 2"));
//Assign data to the data source
_listBox.DisplayMember = "DisplayProperty";
_listBox.ValueMember = "ValueProperty";
_listBox.DataSource = root.MySubObjects;
root.MySubObjects返回SubObject的List,而SubObject必须具有名为DisplayProperty和ValueProperty的属性,例如
public class RootObject
{
public List<SubObject> MySubObjects { get; set; }
}
public class SubObject
{
public string ValueProperty { get; set; }
public string DisplayProperty { get; set; }
}
答案 3 :(得分:0)
我认为你必须在分配到列表框数据源后调用Bind方法 像_listBox.DataSource.bind()之类的东西 并且你的列表框会消失
答案 4 :(得分:0)
您可以尝试使用BindingSource (http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx)
在列表框和您的集合之间。 Bindingsources处理一堆东西,还包括Suspend / ResumeBinding属性,这些属性在更新列表时很有用
你也可以尝试使用wpf,因为它的数据绑定远远优于winforms :)但也许这在你的情况下是不可能的
答案 5 :(得分:0)
我相信你需要调用_listbox.DataBind();在分配数据源之后。 但是,我之前从未使用过属性作为数据源,我只使用了方法。您是否尝试将属性更改为方法以查看是否存在问题?
答案 6 :(得分:0)
你可以尝试
_listBox.DataSource = new BindingList<SubObject> (MyRootObject.MySubObjects);
代替。 BindingList实现了比List更多的接口,这对于DataBinding来说是必不可少的。
答案 7 :(得分:0)
我对这样的问题有一个特殊的规则,我总是试着记住,然后浪费了整整一天的时间(相信我,我已经花了很多天锤击!)。规则是:当系统行为真的很奇怪时,根本原因必须是非常愚蠢的。作为智能程序员,我们倾向于在框架代码中搜索深奥的原因或错误来解释我们的问题。有时答案是我们匆忙并且犯了一个我们还没有抓到的粗心错误。
引用夏洛克·福尔摩斯的话说,“当你删除了不可能的东西时,无论剩下什么,无论多么不可能,都必须是真理”。在这种情况下,不可能的事实是MyRoot对象的MySubObjects属性为null。