<p>I'm making an example for someone who hasn't yet realized that controls like <code>ListBox</code> don't have to contain strings; he had been storing formatted strings and jumping through complicated parsing hoops to get the data back out of the <code>ListBox</code> and I'd like to show him there's a better way.</p>

<p>I noticed that if I have an object stored in the <code>ListBox</code> then update a value that affects <code>ToString</code>, the <code>ListBox</code> does not update itself.  I've tried calling <code>Refresh</code> and <code>Update</code> on the control, but neither works.  Here's the code of the example I'm using, it requires you to drag a listbox and a button onto the form:</p>

<pre><code>Public Class Form1

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)

        For i As Integer = 1 To 3
            Dim tempInfo As New NumberInfo()
            tempInfo.Count = i
            tempInfo.Number = i * 100
            ListBox1.Items.Add(tempInfo)
        Next
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For Each objItem As Object In ListBox1.Items
            Dim info As NumberInfo = DirectCast(objItem, NumberInfo)
            info.Count += 1
        Next
    End Sub
End Class

Public Class NumberInfo

    Public Count As Integer
    Public Number As Integer

    Public Overrides Function ToString() As String
        Return String.Format("{0}, {1}", Count, Number)
    End Function
End Class</code></pre>

<p>I thought that perhaps the problem was using fields and tried implementing <em>INotifyPropertyChanged</em>, but this had no effect.  (The reason I'm using fields is because it's an example and I don't feel like adding a few dozen lines that have nothing to do with the topic I'm demonstrating.)</p>

<p>Honestly I've never tried updating items in place like this before; in the past I've always been adding/removing items, not editing them.  So I've never noticed that I don't know how to make this work.</p>

<p>So what am I missing?</p>

[{'answer_id': 61425, 'author': 'Quibblesome', 'author_id': 1143, 'author_profile': 'https://Stackoverflow.com/users/1143', 'pm_score': 3, 'selected': False, 'text': '<p>Use the datasource property and a BindingSource object in between the datasource and the datasource property of the listbox. Then refresh that.</p>\n\n<p><strong>update</strong> added example.</p>\n\n<p>Like so:</p>\n\n<pre><code>Public Class Form1\n\n    Private datasource As New List(Of NumberInfo)\n    Private bindingSource As New BindingSource\n\n    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)\n        MyBase.OnLoad(e)\n\n        For i As Integer = 1 To 3\n            Dim tempInfo As New NumberInfo()\n            tempInfo.Count = i\n            tempInfo.Number = i * 100\n            datasource.Add(tempInfo)\n        Next\n        bindingSource.DataSource = datasource\n        ListBox1.DataSource = bindingSource\n    End Sub\n\n    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click\n        For Each objItem As Object In datasource\n            Dim info As NumberInfo = DirectCast(objItem, NumberInfo)\n            info.Count += 1\n        Next\n        bindingSource.ResetBindings(False)\n    End Sub\nEnd Class\n\nPublic Class NumberInfo\n\n    Public Count As Integer\n    Public Number As Integer\n\n    Public Overrides Function ToString() As String\n        Return String.Format("{0}, {1}", Count, Number)\n    End Function\nEnd Class\n</code></pre>\n'}, {'answer_id': 61463, 'author': 'zeemz', 'author_id': 6351, 'author_profile': 'https://Stackoverflow.com/users/6351', 'pm_score': -1, 'selected': False, 'text': "<p>I don't know much about vb.net but in C# you should use datasource and then bind it by calling <code>listbox.bind()</code> would do the trick.</p>\n"}, {'answer_id': 61711, 'author': 'Ant', 'author_id': 3709, 'author_profile': 'https://Stackoverflow.com/users/3709', 'pm_score': 2, 'selected': False, 'text': '<p>If you derive from ListBox there is the RefreshItem protected method you can call. Just re-expose this method in your own type.</p>\n\n<pre><code>public class ListBox2 : ListBox {\n    public void RefreshItem2(int index) {\n        RefreshItem(index);\n    }\n}\n</code></pre>\n\n<p>Then change your designer file to use your own type (in this case, ListBox2).</p>\n'}, {'answer_id': 61719, 'author': 'Brad Bruce', 'author_id': 5008, 'author_profile': 'https://Stackoverflow.com/users/5008', 'pm_score': 5, 'selected': False, 'text': "<p>I use this class when I need to have a list box that updates.</p>\n\n<p>Update the object in the list and then call either of the included methods, depending on if you have the index available or not.  If you are updating an object that is contained in the list, but you don't have the index, you will have to call RefreshItems and update all of the items.</p>\n\n<pre><code>public class RefreshingListBox : ListBox\n{\n    public new void RefreshItem(int index)\n    {\n        base.RefreshItem(index);\n    }\n\n    public new void RefreshItems()\n    {\n        base.RefreshItems();\n    }\n}\n</code></pre>\n"}, {'answer_id': 930356, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>It\'s little bit unprofessional, but it works.\nI just removed and added the item (also selected it again).\nThe list was sorted according to "displayed and changed" property so, again, was fine for me. The side effect is that additional event (index changed) is raised.</p>\n\n<pre><code>if (objLstTypes.SelectedItem != null)\n{\n PublisherTypeDescriptor objType = (PublisherTypeDescriptor)objLstTypes.SelectedItem;\n objLstTypes.Items.Remove(objType);\n objLstTypes.Items.Add(objType);\n objLstTypes.SelectedItem = objType;\n}\n</code></pre>\n'}, {'answer_id': 993644, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': -1, 'selected': False, 'text': '<p>If objLstTypes is your ListBox name\nUse\nobjLstTypes.Items.Refresh();\nHope this works...</p>\n'}, {'answer_id': 2135255, 'author': 'geno', 'author_id': 258739, 'author_profile': 'https://Stackoverflow.com/users/258739', 'pm_score': 6, 'selected': True, 'text': '<p>BindingList handles updating the bindings by itself.</p>\n\n<pre><code>using System;\nusing System.ComponentModel;\nusing System.Windows.Forms;\n\nnamespace TestBindingList\n{\n    public class Employee\n    {\n        public string Name { get; set; }\n        public int Id { get; set; }\n    }\n\n    public partial class Form1 : Form\n    {\n        private BindingList&lt;Employee&gt; _employees;\n\n        private ListBox lstEmployees;\n        private TextBox txtId;\n        private TextBox txtName;\n        private Button btnRemove;\n\n        public Form1()\n        {\n            InitializeComponent();\n\n            FlowLayoutPanel layout = new FlowLayoutPanel();\n            layout.Dock = DockStyle.Fill;\n            Controls.Add(layout);\n\n            lstEmployees = new ListBox();\n            layout.Controls.Add(lstEmployees);\n\n            txtId = new TextBox();\n            layout.Controls.Add(txtId);\n\n            txtName = new TextBox();\n            layout.Controls.Add(txtName);\n\n            btnRemove = new Button();\n            btnRemove.Click += btnRemove_Click;\n            btnRemove.Text = "Remove";\n            layout.Controls.Add(btnRemove);\n\n            Load+=new EventHandler(Form1_Load);\n        }\n\n        private void Form1_Load(object sender, EventArgs e)\n        {\n            _employees = new BindingList&lt;Employee&gt;();\n            for (int i = 0; i &lt; 10; i++)\n            {\n                _employees.Add(new Employee() { Id = i, Name = "Employee " + i.ToString() }); \n            }\n\n            lstEmployees.DisplayMember = "Name";\n            lstEmployees.DataSource = _employees;\n\n            txtId.DataBindings.Add("Text", _employees, "Id");\n            txtName.DataBindings.Add("Text", _employees, "Name");\n        }\n\n        private void btnRemove_Click(object sender, EventArgs e)\n        {\n            Employee selectedEmployee = (Employee)lstEmployees.SelectedItem;\n            if (selectedEmployee != null)\n            {\n                _employees.Remove(selectedEmployee);\n            }\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 4285934, 'author': 'Elton M', 'author_id': 521450, 'author_profile': 'https://Stackoverflow.com/users/521450', 'pm_score': 5, 'selected': False, 'text': '<pre><code>lstBox.Items[lstBox.SelectedIndex] = lstBox.SelectedItem;\n</code></pre>\n'}, {'answer_id': 4631419, 'author': 'Jon', 'author_id': 567625, 'author_profile': 'https://Stackoverflow.com/users/567625', 'pm_score': 4, 'selected': False, 'text': '<pre><code>typeof(ListBox).InvokeMember("RefreshItems", \n  BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,\n  null, myListBox, new object[] { });\n</code></pre>\n'}, {'answer_id': 29008084, 'author': 'JTIM', 'author_id': 2076775, 'author_profile': 'https://Stackoverflow.com/users/2076775', 'pm_score': 0, 'selected': False, 'text': '<p>If you use a draw method like:</p>\n\n<pre><code>private void listBox1_DrawItem(object sender, DrawItemEventArgs e)\n{\n    e.DrawBackground();\n    e.DrawFocusRectangle();\n\n    Sensor toBeDrawn = (listBox1.Items[e.Index] as Sensor);\n    e.Graphics.FillRectangle(new SolidBrush(toBeDrawn.ItemColor), e.Bounds);\n    e.Graphics.DrawString(toBeDrawn.sensorName, new Font(FontFamily.GenericSansSerif, 14, FontStyle.Bold), new SolidBrush(Color.White),e.Bounds);\n}\n</code></pre>\n\n<p>Sensor is my class.</p>\n\n<p>So if I change the class <code>Color</code> somewhere, you can simply update it as:</p>\n\n<pre><code>int temp = listBoxName.SelectedIndex;\nlistBoxName.SelectedIndex = -1;\nlistBoxName.SelectedIndex = temp;\n</code></pre>\n\n<p>And the <code>Color</code> will update, just another solution :)</p>\n'}, {'answer_id': 71672910, 'author': 'Daniel Lidström', 'author_id': 286406, 'author_profile': 'https://Stackoverflow.com/users/286406', 'pm_score': 0, 'selected': False, 'text': '<p>If you are doing databinding, try this:</p>\n<pre><code>private void CheckBox_Click(object sender, EventArgs e)\n{\n    // some kind of hack to make the ListBox refresh\n    int currentPosition = bindingSource.Position;\n    bindingSource.Position += 1;\n    bindingSource.Position -= 1;\n    bindingSource.Position = currentPosition;\n}\n</code></pre>\n<p>In this case there is a checkbox that updates an item in a data bound ListBox. Toggling the position of the binding source back and forth seems to work for me.</p>\n'}, {'answer_id': 71919054, 'author': 'John G', 'author_id': 12492467, 'author_profile': 'https://Stackoverflow.com/users/12492467', 'pm_score': 0, 'selected': False, 'text': "<p>Some code that I built some code in VBnet to help do this. The class for anObject has the ToString override to show the object's &quot;title/name&quot;.</p>\n<pre><code>Dim i = LstBox.SelectedIndex\nLstBox.Items(i) = anObject\nLstBox.Sorted = True\n</code></pre>\n"}, {'answer_id': 72072608, 'author': 'purple_2022', 'author_id': 13008103, 'author_profile': 'https://Stackoverflow.com/users/13008103', 'pm_score': 0, 'selected': False, 'text': '<p>you also can try with this fragment of code, it works fine:</p>\n<pre><code>Public Class Form1\n\nDim tempInfo As New NumberInfo()\n\nPrivate Sub Form1_Load() Handles Me.Load\n    For i As Integer = 1 To 3\n        tempInfo.Count = i\n        tempInfo.Number = i * 100\n        ListBox1.Items.Add(tempInfo)\n    Next\nEnd Sub\n\nPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click\n    Dim info As NumberInfo = tempInfo\n    Dim obj As New Object\n    info.Count += 1\n    info.Number = info.Count * 100\n    obj = info\n    ListBox1.Items.Add(obj)\n    ListBox1.Items.RemoveAt(0)\nEnd Sub\nEnd Class\n\nPublic Class NumberInfo\nPublic Count As Integer\nPublic Number As Integer\n    Public Overrides Function ToString() As String\n        Return String.Format(&quot;{0}, {1}&quot;, Count, Number)\n    End Function\nEnd Class\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/61421', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2547/']