簡體   English   中英

ListBox 上的項目顯示為類名

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

問題如下:我使用DataSource屬性將ListBox與某個自定義類( List<Person> persons = new List<Person>() )的元素列表連接起來。 當然ValueMemberDisplayMember都被分配給這個類的適當屬性。 當我第一次加載數據時,一切看起來都很好。 但是,當我單擊某個項目(即第 7 個位置,從 1 開始計數)然后重建列表並且元素數小於 7 時,結果我無法在列表中看到正確的文本。 相反,每個項目都顯示為一個類名,前面是命名空間。

換句話說,而不是列表:

  • 約翰·多伊
  • 簡·多伊
  • 其他人

我看到這個:

  • 我的名字空間.Person
  • 我的名字空間.Person
  • 我的名字空間.Person

看起來它取決於最后的SelectedIndex 如果不再有具有該索引的項目(項目較少),就會出現問題。

我嘗試了重新分配ValueMemberDisplayMember不同組合,以及將 null 分配給列表的DataSource屬性並將列表重新分配給此屬性,甚至嘗試在解除綁定之前將 -1 分配給SelectedIndex ,但它們都沒有幫助。

[編輯]

我被要求展示一些代碼。 我將粘貼相關片段:

一、班級人物:

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. 在 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. 在 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;

當我單擊 button1 時,列表框被填充並且一切正常。 當我選擇最后一項(“Somebode Else”)然后點擊 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;
        }
    }
}

重現問題的步驟:

  1. 運行表單
  2. 單擊按鈕 1
  3. 選擇列表中的最后一個位置(“其他人”)
  4. 單擊按鈕 2

如果您在列表中選擇“John Doe”或“Jane Doe”,則一切正常。 當重建列表后所選索引無效時,它似乎“崩潰”。 我想這是一些錯誤。

當將DataSource設置為null它會清除DisplayMember值。 所以要解決,你設置一個新的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";

否則,在 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;
    }
}

有了這個,每當您將列表框數據源設置為List<Person> ,列表框將自動使用 ToString 方法作為顯示。 使用 selecteditem 只是將其轉換為 Person, (Person)listBox1.SelectedItem

嘗試在任何數據源綁定之前只設置一次“ ValueMember ”和“ DisplayMember ”屬性。 你可以在設計器中設置它們嗎? 然后總是在更改數據源之前,運行 ListBox 的“ ClearSelected() ”方法來清除任何選擇。 然后解除綁定數據源,編輯列表,然后將編輯后的列表設置為數據源。 似乎這種行為是某種錯誤。 試試看是否有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM