问题如下:我使用ListBox
属性将List<Person> persons = new List<Person>()
与某个自定义类(DataSource
)的元素列表相关联。当然,ValueMember
和DisplayMember
都分配给此类的相应属性。当我第一次加载数据时,一切看起来都不错。但是,当我点击某个项目(即第7个位置,从1开始计算)然后重建列表并且元素数量少于7时,因此我无法在列表中看到正确的文本。相反,每个项目都显示为类名,前面是命名空间。
换句话说,而不是列表:
我明白这一点:
看起来它取决于最后SelectedIndex
。如果不再有具有该索引的项目(项目较少),则会出现问题。
我尝试了重新分配ValueMember
和DisplayMember
的不同组合,以及为列表的DataSource
属性分配null并将列表重新分配给此属性,甚至尝试过在取消绑定之前将-1分配给SelectedIndex
,但没有一个帮助。
[编辑]
我被要求显示一些代码。我会粘贴相关的片段:
1。班级人员:
public class Person
{
private int id;
private string name;
public Person(int m_id, string m_name)
{
id = m_id;
name = m_name;
}
public int Id
{
get
{
return id;
}
}
public string Name
{
get
{
return name;
}
}
}`
2。在以下形式的构造函数中:
List<Person> persons = new List<Person>();
第3。在针对buton1点击的方法中点击:
listBox1.DataSource = null; // this is optional. Commenting this line out doesn't help
persons.Add(new Person(1, "John Doe"));
persons.Add(new Person(2, "Jane Doe"));
persons.Add(new Person(3, "Somebody Else"));
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Name";
listBox1.DataSource = persons;
4。在针对buton2点击的方法中点击:
listBox1.DataSource = null; // this is optional. Commenting this line out doesn't help
persons.Add(new Person(1, "Person One"));
persons.Add(new Person(2, "Person Two"));
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Name";
listBox1.DataSource = persons;
当我点击button1时,列表框已填满,一切正常。当我选择最后一项(“Somebode Else”)然后选择clisk button2时,列表框会显示两个相同的项目:“MyNamespace.Person”。
[编辑2 - 完整的表格代码]
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace MyNamespace
{
public partial class Form1 : Form
{
private List<Person> persons = new List<Person>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
persons.Clear();
persons.Add(new Person(1, "John Doe"));
persons.Add(new Person(2, "Jane Doe"));
persons.Add(new Person(1, "Somebody Else"));
listBox1.DataSource = null;
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Name";
listBox1.DataSource = persons;
}
private void button2_Click(object sender, EventArgs e)
{
persons.Clear();
persons.Add(new Person(1, "Person One"));
persons.Add(new Person(2, "Person Two"));
listBox1.DataSource = null;
listBox1.ValueMember = "Id";
listBox1.DisplayMember = "Name";
listBox1.DataSource = persons;
}
}
class Person
{
private int id;
private string name;
public Person(int m_id, string m_name)
{
id = m_id;
name = m_name;
}
public int Id
{
get
{
return id;
}
}
public string Name
{
get
{
return name;
}
}
public string ToString()
{
return id + ". " + name;
}
}
}
重现问题的步骤:
如果您在列表中选择“John Doe”或“Jane Doe”,一切正常。当重建列表后所选索引无效时,它似乎“崩溃”。我猜这是一些错误。
答案 0 :(得分:11)
在Person类中重写ToString方法:
public class Person
{
private int id;
private string name;
public Person(int m_id, string m_name)
{
id = m_id;
name = m_name;
}
public int Id
{
get
{
return id;
}
}
public string Name
{
get
{
return name;
}
}
public override string ToString()
{
return name;
}
}
每当您将列表框数据源设置为List<Person>
时,列表框将自动使用ToString方法作为显示。使用selecteditem只需将其转换为Person (Person)listBox1.SelectedItem
。
当您将数据源设置为null
时,还有一些调查并发现它清除了DisplayMemeber值。在设置新的数据源后设置它,问题就消失了。
listBox1.DataSource = null; // this is optional. Commenting this line out doesn't help
persons.Add(new Person(1, "John Doe"));
persons.Add(new Person(2, "Jane Doe"));
persons.Add(new Person(3, "Somebody Else"));
listBox1.DataSource = persons;
listBox1.DisplayMember = "Name";
答案 1 :(得分:0)
尝试在任何数据源绑定之前仅设置一次“ ValueMember ”和“ DisplayMember ”属性。你能在设计师中设置它们吗?然后总是在更改数据源之前,运行ListBox的“ ClearSelected()” - 方法来清除任何选择。然后取消绑定数据源,编辑列表,然后将编辑后的列表设置为数据源。似乎这种行为是某种错误。试试这是否有帮助。