使用构造函数填充列表会覆盖以前的信息

问题描述 投票:1回答:1

我还是C#的新手,所以我不知道它有什么可能性。

我的代码:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Test ctest = new Test();

        private void button1_Click(object sender, EventArgs e)
        {
            ctest.name = Convert.ToString(textBox1.Text);
            MessageBox.Show(ctest.name);
            ctest.namelist.Add(ctest);
            listBox1.DataSource = null;
            listBox1.DataSource = ctest.namelist;
        }
    }


    class Test
    {

        private string Name;

        public string name
        {
            get { return Name; }
            set { Name = value; }
        }


        public List<Test> namelist = new List<Test>();

        public override string ToString()
        {
            string spaceinbetween = new string(' ', 3);
            return name + spaceinbetween + name;
        } 

我正在尝试做什么:所以我想使用我的构造函数来填充我的列表框中的信息(在这种情况下是名称)。但是,在添加2个以上的名称后,它会覆盖以前的值。

我认为这是错误的,因为类对象名称被覆盖并在添加的两个行中使用。

问题:无论如何,添加新名称不会改变以前的列表值,或者是否有任何方法可以在我创建新的ctest的任何时候创建构造函数的新实例?

c# list constructor
1个回答
1
投票

如果我没有误解您的问题,那么有很多事情需要改变以使您的表单正常工作:

public partial class Form1 : Form
{
    // BindingList is perfect here... istead of List. It automatically refreshes upon change.
    private BindingList<Test> m_Tests;

    public Form1()
    {
        InitializeComponent();

        m_Tests = new BindingList<Test>();

        listBox1.DataSource = m_Tests;
        // DisplayMember and ValueMember should be defined too here.
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // Create a new instance every time the button is clicked.
        // Since textBox1.Text is already a String... no need to convert it!
        // Thanks to BindingList, you don't need to refresh your binding...
        m_Tests.Add(new Test(textBox1.Text));
    }
}

public class Test
{
    private String m_Name;

    public String Name
    {
        get { return m_Name; }
        set { m_Name = value; }
    }

    public Test(String name)
    {
        m_Name = name;
    }

    public override String ToString()
    {
        if (String.IsNullOrWhiteSpace(m_Name))
            return "NO NAME";

        return (m_Name + "   " + m_Name);
    }
}

让我们总结一下我的变化:

  1. 该列表不应该是你的Test类的一部分,而是你的Form1。这是在OOP观点上应该正确添加和管理新实例的地方。
  2. 由于您将列表绑定到ListBox控件,因此最好使用BindingList(参考here)。它完全是为了这个目的而制作的,它可以自动处理变化。
  3. 当调用BindingList构造函数时,可以初始化Form1,并且必须在同一上下文中定义它与ListBox控件的链接。不要忘记为listBox1.DisplayMemberlistBox1.ValueMember属性增值,以便设置适当的基础数据显示。
  4. 单击该按钮时,您所要做的就是创建Test类的新实例,其名称由textBox1.Text定义,并将其添加到BindingList
  5. 使用之前的方法,因为在Test类中创建了单个Form1类实例,所以每次单击按钮时,您都尝试添加完全相同的实例...而这基本上没有产生任何结果。
  6. 您可以为接受名称作为参数的Test类定义自定义构造函数,以便于创建新实例。
  7. 正确处理你的Test.ToString()覆盖以避免问题。
  8. 总的来说,使用正确的命名约定来提高代码的可读性。
© www.soinside.com 2019 - 2024. All rights reserved.