ListBox 上的项目显示为类名 [英] Items on ListBox show up as a class name

查看:15
本文介绍了ListBox 上的项目显示为类名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题如下:我将 ListBox 与一些自定义类的元素列表连接起来(Listpersons = new List()) 使用 DataSource 属性.当然 ValueMemberDisplayMember 都被分配给这个类的适当属性.当我第一次加载数据时,一切看起来都很好.但是,当我单击某个项目(即第 7 位,从 1 开始计数)然后重建列表并且元素数量少于 7 时,结果我无法在列表中看到正确的文本.相反,每个项目都显示为一个类名,前面是命名空间.

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. Of course ValueMember and DisplayMember are both assigned to appropriate properties of this class. When I first load data, everything looks ok. However, when I click on some item (i.e. 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. Instead, every item shows up as a class name, preceded by the namespace.

换句话说,而不是列表:

In other words, instead of the list:

  • 约翰·多伊
  • 简·多伊
  • 别人

我看到了:

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

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

It looks like it depends on last SelectedIndex. If there is no longer an item with that index (there are less items), the problem occurs.

我尝试了重新分配 ValueMemberDisplayMember 的不同组合,以及将 null 分配给列表的 DataSource 属性并重新分配该属性的列表,甚至尝试在解除绑定之前将 -1 分配给 SelectedIndex,但它们都没有帮助.

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.

我被要求展示一些代码.我将粘贴相关片段:

I was asked to show some code. I'll paste the relevant fragments:

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.在表单的构造函数中:

列表<人员>人员 = 新列表<人员>();

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.在按钮 2 上触发的方法中单击:

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")然后单击按钮 2 时,列表框显示 2 个相同的项目:MyNamespace.Person".

When I click button1, the listbox is filled and everything works fine. When I select last item ("Somebode Else") and then clisk button2, the listbox shows 2 identical items: "MyNamespace.Person".

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

重现问题的步骤:

  1. 运行表单
  2. 点击按钮1
  3. 选择列表中的最后一个位置(其他人")
  4. 点击按钮2

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

If you select "John Doe" or "Jane Doe" on the list, everything works fine. It seems to "crash" when the selected index is not valid after rebuilding the list. I guess it's some bug.

推荐答案

当将 DataSource 设置为 null 时,它会清除 DisplayMember 值.所以要解决,你设置一个新的DataSource之后设置它,问题就消失了.

When one sets the DataSource to null it clears the DisplayMember value. So to resolve, set it after you set a new DataSource and the problem disappears.

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


否则在 Person 类中重写 ToString 方法以确保在 DataMember 为空时显示正确的属性:


Otherwise in the Person class override the ToString method to ensure that the proper property will be shown if DataMember is empty:

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 时,列表框将自动使用 ToString 方法作为显示.使用 selecteditem 只需将其转换为 Person,(Person)listBox1.SelectedItem.

With this whenever you set the listbox datasource to a List<Person> the listbox will automatically use the ToString method as the display. Using the selecteditem is simply a matter of casting it as Person, (Person)listBox1.SelectedItem.

这篇关于ListBox 上的项目显示为类名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆