简体   繁体   English

ListBox 上的项目显示为类名

[英]Items on ListBox show up as a class name

The problem is as follows: I connected the ListBox with a list of elements of some custom class ( List<Person> persons = new List<Person>() ) using DataSource property.问题如下:我使用DataSource属性将ListBox与某个自定义类( List<Person> persons = new List<Person>() )的元素列表连接起来。 Of course ValueMember and DisplayMember are both assigned to appropriate properties of this class.当然ValueMemberDisplayMember都被分配给这个类的适当属性。 When I first load data, everything looks ok.当我第一次加载数据时,一切看起来都很好。 However, when I click on some item (ie 7th position, counting from 1) and then rebuild the list AND the number of elements is LESS than 7, as a result I can't see the proper texts on the list.但是,当我单击某个项目(即第 7 个位置,从 1 开始计数)然后重建列表并且元素数小于 7 时,结果我无法在列表中看到正确的文本。 Instead, every item shows up as a class name, preceded by the namespace.相反,每个项目都显示为一个类名,前面是命名空间。

In other words, instead of the list:换句话说,而不是列表:

  • John Doe约翰·多伊
  • Jane Doe简·多伊
  • Somebody Else其他人

I see this:我看到这个:

  • MyNamespace.Person我的名字空间.Person
  • MyNamespace.Person我的名字空间.Person
  • MyNamespace.Person我的名字空间.Person

It looks like it depends on last SelectedIndex .看起来它取决于最后的SelectedIndex If there is no longer an item with that index (there are less items), the problem occurs.如果不再有具有该索引的项目(项目较少),就会出现问题。

I've tried different combinations of reassigning ValueMember and DisplayMember , as well as assigning null to the DataSource property of the list and reassign the list to this property, even tried to assign -1 to SelectedIndex before unbinding, but none of them helped.我尝试了重新分配ValueMemberDisplayMember不同组合,以及将 null 分配给列表的DataSource属性并将列表重新分配给此属性,甚至尝试在解除绑定之前将 -1 分配给SelectedIndex ,但它们都没有帮助。

[Edit] [编辑]

I was asked to show some code.我被要求展示一些代码。 I'll paste the relevant fragments:我将粘贴相关片段:

1. Class Person:一、班级人物:

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. In a constructor of the form: 2. 在窗体的构造函数中:

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

3. In a method fired on buton1 click: 3. 在 button1 单击触发的方法中:

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. In a method fired on buton2 click: 4. 在 button2 上触发的方法中单击:

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;

When I click button1, the listbox is filled and everything works fine.当我单击 button1 时,列表框被填充并且一切正常。 When I select last item ("Somebode Else") and then clisk button2, the listbox shows 2 identical items: "MyNamespace.Person".当我选择最后一项(“Somebode Else”)然后点击 button2 时,列表框显示 2 个相同的项目:“MyNamespace.Person”。

[Edit 2 - complete code of form] [编辑 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;
        }
    }
}

Steps to reproduce the problem:重现问题的步骤:

  1. Run the form运行表单
  2. Click button1单击按钮 1
  3. Select last position on the list ("Somebody Else")选择列表中的最后一个位置(“其他人”)
  4. Click button2单击按钮 2

If you select "John Doe" or "Jane Doe" on the list, everything works fine.如果您在列表中选择“John Doe”或“Jane Doe”,则一切正常。 It seems to "crash" when the selected index is not valid after rebuilding the list.当重建列表后所选索引无效时,它似乎“崩溃”。 I guess it's some bug.我想这是一些错误。

When one sets the DataSource to null it clears the DisplayMember value.当将DataSource设置为null它会清除DisplayMember值。 So to resolve, set it after you set a new DataSource and the problem disappears.所以要解决,你设置一个新的DataSource设置它,问题就消失了。

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";

Otherwise in the Person class override the ToString method to ensure that the proper property will be shown if DataMember is empty:否则,在 Person 类中重写ToString方法以确保在DataMember为空时显示正确的属性:

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;
    }
}

With this whenever you set the listbox datasource to a List<Person> the listbox will automatically use the ToString method as the display.有了这个,每当您将列表框数据源设置为List<Person> ,列表框将自动使用 ToString 方法作为显示。 Using the selecteditem is simply a matter of casting it as Person, (Person)listBox1.SelectedItem .使用 selecteditem 只是将其转换为 Person, (Person)listBox1.SelectedItem

Try setting the " ValueMember " and " DisplayMember " properties only once before any datasource binding.尝试在任何数据源绑定之前只设置一次“ ValueMember ”和“ DisplayMember ”属性。 Can you set them in the designer?你可以在设计器中设置它们吗? Then always before changing the datasource, run ListBox's " ClearSelected() "-method to clear any selections.然后总是在更改数据源之前,运行 ListBox 的“ ClearSelected() ”方法来清除任何选择。 Then unbind the datasource, edit the list, then set the edited list as datasource.然后解除绑定数据源,编辑列表,然后将编辑后的列表设置为数据源。 Seems that this behavior is some kind of bug.似乎这种行为是某种错误。 Try if this helps.试试看是否有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM