Click here to Skip to main content
15,885,029 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
I have a ListBox on a form.

When I add a new item to the ListBox, I am adding a custom class called Query. In the Query class I have overridden the ToString() method to display the Name property.

This works great when I add all of the new items. They are stored correctly in the ListBox and they are displayed correctly.

My problem comes when I try to rename a Query. I have a ContextMenuStrip that I use and a simple InputBox to allow the user to rename the item. It works properly and renames the Name property of the Query, however, it does not update what is displayed in the ListBox.

Example:
When I click the "Add" button, it adds a new Query with the name "New Dataset". Then, the user right-clicks on that item and they click the "Rename" button. This loads up an InputBox asking them to enter a new name and loads the original name into the InputBox.

The user enters a new name hits enter and I run:
C#
//In C#
((MyMDX.Query)lboDataSets.SelectedItem).Name = newName;

VB
'In VB.NET
CType(lboDataSets.SelectedItem, myMDX.Query).Name = newName


This does update the SelectedItem to reflect the new name, however, the displayed value of the Item in the ListBox is still "New Dataset".

I have tried running lboDataSets.Invalidate(), lboDataSets.Refresh(), lboDataSets.BeginUpdate()/lboDataSets.EndUpdate and I have tried changing lboDataSets.SelectedValue() and nothing updates the displayed value.

So, how can I get the displayed value to update?

[Update]
No one has an answer? I was able to fake it by storing the Query as a temporary object and then removing the original item, and inserting the temp object back into the original place, but that seems more like a work-around than an actual solution.

Luc:
I'm on the main thread...the one that the ListBox was created on. So, I don't need to use Invoke at that point. And I've tried Invalidate(), but like you said, it seems to store the name statically and it doesn't change when the underlying data changes. I've tried both Invalidate() and Refresh() and neither one forces a call back to the ToString() function.
Posted
Updated 6-Apr-10 12:30pm
v3
Comments
William Winner 14-Oct-10 11:15am    
test

Hi,

clearly just changing the Name of some object (say a Query instance) does not cause a ListBox to update itself, as their is no forward connection from the Query instance to the ListBox; the only connection that exists is a backward one, the ListBox knowing it is showing some Query objects.

So you need to tell the ListBox something needs to be done, using the Invalidate() or the Refresh() methods. However a ListBox is a Control, which means you are not allowed to touch it from just any thread you like. So you need the Control.InvokeRequires/Control.Invoke pattern which I described here[^].

If you are sure you're on the wrong thread, and since you don't need to pass any parameters, it could be simplified to
lboDataSets.Invoke(new MethodInvoker(delegate() {
    lboDataSets.Invalidate();
}));


:)
 
Share this answer
 
SQL
Dim i As Integer
        i = ListBox1.SelectedIndex.ToString
        ListBox1.Items.RemoveAt(ListBox1.SelectedIndex.ToString)
        ListBox1.Items.Insert(i, TextBox3.Text)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900