Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Windows Forms
  4. ListBox does not update when DataSource is changed

ListBox does not update when DataSource is changed

Scheduled Pinned Locked Moved Windows Forms
helpquestionannouncement
23 Posts 5 Posters 42 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R rbsbscrp

    Wow but this is weird. Okay, I found the solution because I tried the recommendation given below:

    lbxQuotes.DataSource = null;
    lbxQuotes.DataSource = _quotes;
    lbxQuotes.SelectionMode = SelectionMode.None;
    lbxQuotes.SelectionMode = SelectionMode.One;

    That is, I added the SelectionMode two lines... and this caused (only once) a "from different thread" exception. Weird, I'm NOT running a method - I'm changing data... hmmm... I wonder if the DataSource is instead a Property (which secretly runs a method). D'oh! Okay, so the solution was to create a delegate in the main form, for the RefreshLbx method, and have the RefreshLbx method recursively call this, as below:

    public void RefreshLbx()
    {
    if (lbxQuotes.InvokeRequired)
    {
    lbxQuotes.Invoke(_refreshLbx);
    }
    else
    {
    lbxQuotes.DataSource = null;
    lbxQuotes.DataSource = _quotes;
    }
    }

    with the _refreshLbx delegate defined in the form's class as:

    private delegate void RefreshLbxDg8();
    private RefreshLbxDg8 _refreshLbx;

    Then just init the delegate in the form constructor (after the InitializeComponent() call):

        \_refreshLbx = RefreshLbx;
    

    Now I am able to update the listbox contents from a timer handler.

    T Offline
    T Offline
    TnTinMn
    wrote on last edited by
    #21

    I know that this is a bit late, but have you ever considered using the BindingList(Of T) Class[^] instead? It will notify any changes to the list so that the bound control can take action.

    R 1 Reply Last reply
    0
    • T TnTinMn

      I know that this is a bit late, but have you ever considered using the BindingList(Of T) Class[^] instead? It will notify any changes to the list so that the bound control can take action.

      R Offline
      R Offline
      rbsbscrp
      wrote on last edited by
      #22

      I'm not familiar with BindingList. I took a quick look at the link but am unsure of its benefit here. Thx for the heads up, though.

      T 1 Reply Last reply
      0
      • R rbsbscrp

        I'm not familiar with BindingList. I took a quick look at the link but am unsure of its benefit here. Thx for the heads up, though.

        T Offline
        T Offline
        TnTinMn
        wrote on last edited by
        #23

        Perhaps I misunderstood your problem, I thought that it was that the ListBox was not automatically reflecting changes to the underlying DataSource List. The BindingList raises events that would cause the ListBox to update automatically when the List changes. Here is a simple example. New WinForm project with two buttons and two ListBoxes. Clicking Button1 adds items to the underlying lists, but only the ListBox with the BindingList as the DataSource is update. Clicking Button2 tells ListBox1 to Refresh it's data.

        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Text;
        using System.Windows.Forms;

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

            List<int> L1 = new List<int>();
            BindingList<int> L2 = new BindingList<int>();
            private void Form1\_Load(object sender, EventArgs e)
            {
                L1.Add(1);
                L1.Add(2);
                L2.Add(11);
                L2.Add(22);
                listBox1.DataSource = L1;
                listBox2.DataSource = L2;
                this.button1.Click += new System.EventHandler(this.button1\_Click);
                this.button2.Click += new System.EventHandler(this.button2\_Click);
            }
        
            private void button1\_Click(object sender, EventArgs e)
            {
                L1.Add(3);  // adds a value to L1, but listBox1 does not display it until the binding is refresshed
                L2.Add(33); // adds a value to L2 and listBox2 is automatically refreshed to display it
            }
        
            private void button2\_Click(object sender, EventArgs e)
            {
                // tell listBox1 to refresh the data
                ((CurrencyManager)this.BindingContext\[L1\]).Refresh();
            }
        }
        

        }

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups