如何在列表框中刷新条目文本而不重新插入它

本文关键字:新插入 插入 文本 列表 刷新 | 更新日期: 2023-09-27 18:17:59

我有覆盖ToString的类TestClass(它返回Name字段)。我有TestClass的实例添加到ListBox,在某些时候我需要改变Name的一个实例,然后我怎么能刷新它的文本在ListBox ?

using System;
using System.Windows.Forms;
namespace TestListBox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            listBox1.Items.Add(new TestClass("asd"));
            listBox1.Items.Add(new TestClass("dsa"));
            listBox1.Items.Add(new TestClass("wqe"));
            listBox1.Items.Add(new TestClass("ewq"));
        }
        private void button1_Click(object sender, EventArgs e)
        {
            ((TestClass)listBox1.Items[0]).Name = "123";
            listBox1.Refresh(); // doesn't help
            listBox1.Update(); // same of course
        }
    }
    public class TestClass
    {
        public string Name;
        public TestClass(string name)
        {
            this.Name = name;
        }
        public override string ToString()
        {
            return this.Name;
        }
    }
}

如何在列表框中刷新条目文本而不重新插入它

try

listBox1.Items[0] = listBox1.Items[0];

我遇到过同样的问题,并尝试了各种不同的方法来尝试让项目的显示文本实际反映底层项目值。在浏览了所有可用的属性后,我发现这是最简单的。 lbGroupList.DrawMode = DrawMode.OwnerDrawFixed; lbGroupList.DrawMode = DrawMode.Normal; 它触发控件内的适当事件来更新显示的文本。

您的Testclass需要实现INotifyPropertyChanged

public class TestClass : INotifyPropertyChanged
{
    string _name;
    public string Name
    {
        get { return _name;}
        set 
        {
              _name = value;
              _notifyPropertyChanged();
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void _notifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
    }
    public TestClass(string name)
    {
        this.Name = name;
    }
    public override string ToString()
    {
        return this.Name;
    }
}

然而,这只适用于当你使用的列不依赖于ToString(),但绑定属性Name

这可以通过修改你的代码来完成:

在class declare

的某处
BindingList<TestClass> _dataSource = new BindingList<TestClass>();

在initializeComponent中写入

listBox1.DataSource = _dataSource;

然后对_dataSource而不是Listbox进行所有操作

你可以使用BindingList:

        items = new BindingList<TestClass>( );
        listBox1.DataSource = items;
        listBox1.DisplayMember = "_Name";

然后刷新列表调用:

        items.ResetBindings( );
也不要忘记为Name 创建一个get属性
      public string _Name
    {
        get { return Name; }
        set { Name= value; }
    }

我使用以下代码:

public static void RefreshItemAt (ListBox listBox, int itemIndex)
{
    if (itemIndex >= 0)
    {
        Rectangle itemRect = listBox.GetItemRectangle(itemIndex);
        listBox.Invalidate(itemRect);
        listBox.Update();
    }
}