Solved

DataBinding an ArrayList to a ListBox and updating

Posted on 2004-08-31
11
2,143 Views
Last Modified: 2011-09-20
Hi,

I have a ListBox which is bound to an ArrayList like so:

ArrayList *JumpPoints = new ArrayList();
ListBox *lbBeacons = new ListBox();

...etc...

lbBeacons->DataSource = JumpPoints;
lbBeacons->DisplayMember =S"BeaconString";

And all works fine until the ArrayList changes but the ListBox doesn't refresh in any way that reflects the changes. I have looked around and come across CurrencyManagers/BindingManagers but can find no coherent examples in VC++ that cover what I need.

Which is the best way to go to achieve this? Can anyone give a clear code example in VC++?

Many thanks.
0
Comment
Question by:grokuk
  • 4
  • 3
  • 2
  • +2
11 Comments
 
LVL 16

Expert Comment

by:nonubik
ID: 11941700
When the DataSource property is set, a user cannot modify the items collection.

I think you'll need to re set the DataSource
0
 

Author Comment

by:grokuk
ID: 11951512
I've tried reassigning the DataSource to zero and then back again to the ArrayList, but no improvement.
0
 
LVL 16

Expert Comment

by:nonubik
ID: 11980653
Have you tried to call DataBind() ?
0
 
LVL 6

Accepted Solution

by:
Svetlin_Panayotov earned 500 total points
ID: 12023848
//When ArrayList changes
lbBeacons->DataSource = NULL;
lbBeacons->DataSource = JumpPoints;

This works for me.Well it's not the best way but refresh seems to be OK.

Svetlin

0
 
LVL 3

Expert Comment

by:Statick001
ID: 12054667
what i usually do is define a function which is called whenever the listbox needs to be updated...
inside this function i define and fill the arraylist, and bind it to the list box.

because the arraylist only exists in this local scope, every time this function is called the listbox is updated accordingly

i also include code at the beginning and end of the function which preserves the selected index - so if the data is refreshed on a timer, the user doesnt get interrupted.

void Reload_Data()
{

   // store selected index
   int index = this->Listbox->SelectedIndex;

   // create arraylist
   ArrayList * data = new ArrayList();

   // fill arraylist with relevant information
   // ...

   // bind arraylist to listbox
   this->Listbox->ValueMember = S"ID";
   this->Listbox->DisplayMember = S"Name";
   this->Listbox->DataSource = data;

   // restore selected index
   this->Listbox->SelectedIndex = index;
}

if you need to preserve your existing arraylist, you could pass it to this function like this

void Reload_Data(ArrayList * data)
{
    // ...
}

then call it as...
Reload_Data(JumpPoints);

when you call the function, your exsiting arraylist will be copied to a new one called 'data' which will only exist in the local scope, and the function will behave as expected

hope this helps
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 3

Expert Comment

by:Statick001
ID: 12054686
sorry forgot to mention - if you define the function with parameters (ArrayList * data) then obviously you must remove the ArrayList definition inside the function or you will get a compiler error !

0
 

Expert Comment

by:fdelagarza
ID: 12243874
I've run through the same problem with the difference that I program in C#.
But the solution should be the same.

Here is what I did....


ArrayList *JumpPoints = new ArrayList();
ListBox *lbBeacons = new ListBox();
lbBeacons->DataSource = JumpPoints;
lbBeacons->DisplayMember =S"BeaconString";

/****************whatever changes your arraylist*******************/
/*************************************************/

/*****************refreshing!!!! ************/
// Unbind the grid
lbBeacons->DataSource = null;
// Bind the grid
lbBeacons->DataSource = JumpPoints;
// This will refresh the currency manager.....
CurrencyManager currencymanager = (CurrencyManager)lbBeacons->BindingContext[JumpPoints];
currencymanager->Refresh();
/*****************finish refreshing!!!! ************/


Hope this works for you.......
Fernando de la Garza

0
 

Author Comment

by:grokuk
ID: 12369192
Thanks to those who've answered, but I'm still looking for a working VC++ (.NET) example.

Setting the DataSource to NULL and then back to the ArrayList does almost work, but it leaves a number of 'empty' items in the ListBox (despite reassigning the Display and Value Members).

The CurrencyManager approach of Fernando looks like the right sort of thing, but C++ handles the BindingContext in a rather different way to C#. Or at least, I can't find any equivalent to the lbBeacons->BindContect[JumpPoints] indirection that works. Maybe I'm missing something obvious?

Still searching....

0
 
LVL 3

Expert Comment

by:Statick001
ID: 12369239
i think you will find my method shown above works just fine. i have millions of listboxes, comboboxes and datagrids in my applications, which all use that method.

to re-iterate - define and fill the arraylist within a function. bind the arraylist to the listbox in the same function. whenever you want to update the listbox, simply call the function. because the arraylist is in local scope to that function, every time you call it the listbox sees a 'new' arraylist, and updates itself with the new data.

0
 
LVL 3

Expert Comment

by:Statick001
ID: 12369258
and of course, every time the list is refreshed, the previous arraylist no longer has any references to it, and so the garbage collector will deal with it accordingly
0
 

Author Comment

by:grokuk
ID: 12372189
Thanks Statick but I was hoping to find a solution that avoided re-iterating through the full list each time.

It turns out that I owe an apology to Svetlin_Panayotov as his solution does in fact work perfectly if you also reassign the DisplayMember as well as the DataSource.

In Short:

lbBeacons->DataSource = NULL;
lbBeacons->DataSource = JumpPoints;
lbBeacons->DisplayMember =S"BeaconString";

Does the trick.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now