ListBox上的项目显示为类名

pet*_*erp 5 c# listbox selectedindex winforms

问题如下:我使用property 连接了ListBox一些自定义class(List<Person> persons = new List<Person>())的元素列表DataSource.当然ValueMember,DisplayMember它们都被赋予了这个类的适当属性.当我第一次加载数据时,一切看起来都不错.但是,当我点击某个项目(即第7个位置,从1开始计算)然后重建列表并且元素数量少于7时,因此我无法在列表中看到正确的文本.相反,每个项目都显示为类名,前面是命名空间.

换句话说,而不是列表:

  • 约翰·多伊
  • 简·多伊
  • 其他人

我看到了这个:

  • MyNamespace.Person
  • MyNamespace.Person
  • MyNamespace.Person

看起来它取决于最后SelectedIndex.如果不再有具有该索引的项目(项目较少),则会出现问题.

我试图重新分配的不同组合ValueMemberDisplayMember,以及在分配空DataSource列表的属性并重新分配名单这个属性,甚至试图分配-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;
        }
    }
}`
Run Code Online (Sandbox Code Playgroud)

2.在形式的构造函数中:

List<Person> persons = new List<Person>();

3.在onon1上触发的方法中单击:

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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

当我单击button1时,列表框已填满,一切正常.当我选择最后一项("Somebode Else")然后clisk button2时,列表框显示2个相同的项目:"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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

重现问题的步骤:

  1. 运行表单
  2. 单击button1
  3. 选择列表中的最后位置("Somebody Else")
  4. 单击button2

如果您在列表中选择"John Doe"或"Jane Doe",一切正常.当重建列表后所选索引无效时,它似乎"崩溃".我想这是一些错误.

tin*_*afl 12

在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

每当您将列表框数据源设置为列表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";
Run Code Online (Sandbox Code Playgroud)