472,126 Members | 1,628 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,126 software developers and data experts.

Listbox does not display the changes made to an object

(If you've seen this in the drawing NG, sorry. I inadvertently sent it
there.)
I have a listbox populated with Objects.

The Class has a String field that ToString returns.

I assume that is what the ListBox uses for its display. Correct?

If I change the value of the object's string field the ListBox display does
not change. Would you expect it to change?

The Debugger shows that the item does in fact have the new value even though
the display has not changed.

I tried putting
ListBox1.SuspendLayout() and ListBox1.ResumeLayout() around the change code
to see it by chance that would trigger a change in display but it didn't. I
didn't really expect it would.

So I added code to remove and then add the item:

Dim j As Object = ListBox1.Items(ListBox1.SelectedIndex)

Dim i As Integer = ListBox1.SelectedIndex

ListBox1.Items.RemoveAt(i)

ListBox1.Items.Insert(i, j)

ListBox1.SelectedIndex = i

That works. Now as soon as the Object is changed the new value displays.

But I can't say I like it.

Isn't there a better way?

Thanks for any help

PS The ListBox appears to generate a list of strings so that it does not
have to access the objects when a Paint is required? Is that your
understanding?


Nov 2 '07 #1
5 2728
On Nov 2, 9:39 am, "Academia" <academiaNOS...@a-znet.comwrote:
(If you've seen this in the drawing NG, sorry. I inadvertently sent it
there.)

I have a listbox populated with Objects.

The Class has a String field that ToString returns.

I assume that is what the ListBox uses for its display. Correct?

If I change the value of the object's string field the ListBox display does
not change. Would you expect it to change?

The Debugger shows that the item does in fact have the new value even though
the display has not changed.

I tried putting
ListBox1.SuspendLayout() and ListBox1.ResumeLayout() around the change code
to see it by chance that would trigger a change in display but it didn't. I
didn't really expect it would.

So I added code to remove and then add the item:

Dim j As Object = ListBox1.Items(ListBox1.SelectedIndex)

Dim i As Integer = ListBox1.SelectedIndex

ListBox1.Items.RemoveAt(i)

ListBox1.Items.Insert(i, j)

ListBox1.SelectedIndex = i

That works. Now as soon as the Object is changed the new value displays.

But I can't say I like it.

Isn't there a better way?

Thanks for any help

PS The ListBox appears to generate a list of strings so that it does not
have to access the objects when a Paint is required? Is that your
understanding?
Will a call to ListBox.Refresh() or ListBox.Invalidate() work?

Thanks,

Seth Rowe

Nov 2 '07 #2
I should have mentioned that I had also tried ListBox.Refresh.

Thanks

"rowe_newsgroups" <ro********@yahoo.comwrote in message
news:11*********************@v3g2000hsg.googlegrou ps.com...
On Nov 2, 9:39 am, "Academia" <academiaNOS...@a-znet.comwrote:
>(If you've seen this in the drawing NG, sorry. I inadvertently sent it
there.)

I have a listbox populated with Objects.

The Class has a String field that ToString returns.

I assume that is what the ListBox uses for its display. Correct?

If I change the value of the object's string field the ListBox display
does
not change. Would you expect it to change?

The Debugger shows that the item does in fact have the new value even
though
the display has not changed.

I tried putting
ListBox1.SuspendLayout() and ListBox1.ResumeLayout() around the change
code
to see it by chance that would trigger a change in display but it didn't.
I
didn't really expect it would.

So I added code to remove and then add the item:

Dim j As Object = ListBox1.Items(ListBox1.SelectedIndex)

Dim i As Integer = ListBox1.SelectedIndex

ListBox1.Items.RemoveAt(i)

ListBox1.Items.Insert(i, j)

ListBox1.SelectedIndex = i

That works. Now as soon as the Object is changed the new value displays.

But I can't say I like it.

Isn't there a better way?

Thanks for any help

PS The ListBox appears to generate a list of strings so that it does not
have to access the objects when a Paint is required? Is that your
understanding?

Will a call to ListBox.Refresh() or ListBox.Invalidate() work?

Thanks,

Seth Rowe

Nov 2 '07 #3
On Fri, 2 Nov 2007 09:39:52 -0400, "Academia"
<ac************@a-znet.comwrote:
>(If you've seen this in the drawing NG, sorry. I inadvertently sent it
there.)
I have a listbox populated with Objects.

The Class has a String field that ToString returns.

I assume that is what the ListBox uses for its display. Correct?

If I change the value of the object's string field the ListBox display does
not change. Would you expect it to change?

The Debugger shows that the item does in fact have the new value even though
the display has not changed.

I tried putting
ListBox1.SuspendLayout() and ListBox1.ResumeLayout() around the change code
to see it by chance that would trigger a change in display but it didn't. I
didn't really expect it would.

So I added code to remove and then add the item:

Dim j As Object = ListBox1.Items(ListBox1.SelectedIndex)

Dim i As Integer = ListBox1.SelectedIndex

ListBox1.Items.RemoveAt(i)

ListBox1.Items.Insert(i, j)

ListBox1.SelectedIndex = i

That works. Now as soon as the Object is changed the new value displays.

But I can't say I like it.

Isn't there a better way?

Thanks for any help

PS The ListBox appears to generate a list of strings so that it does not
have to access the objects when a Paint is required? Is that your
understanding?
I think that if the Object implements INotifyPropertyChanged that will
fix it. If you Google for that you can find some examples of how to
use it.

I have no idea about the Paint questions.
Nov 2 '07 #4
On Nov 2, 10:19 am, Jack Jackson <jacknos...@pebbleridge.comwrote:
On Fri, 2 Nov 2007 09:39:52 -0400, "Academia"

<academiaNOS...@a-znet.comwrote:
(If you've seen this in the drawing NG, sorry. I inadvertently sent it
there.)
I have a listbox populated with Objects.
The Class has a String field that ToString returns.
I assume that is what the ListBox uses for its display. Correct?
If I change the value of the object's string field the ListBox display does
not change. Would you expect it to change?
The Debugger shows that the item does in fact have the new value even though
the display has not changed.
I tried putting
ListBox1.SuspendLayout() and ListBox1.ResumeLayout() around the change code
to see it by chance that would trigger a change in display but it didn't. I
didn't really expect it would.
So I added code to remove and then add the item:
Dim j As Object = ListBox1.Items(ListBox1.SelectedIndex)
Dim i As Integer = ListBox1.SelectedIndex
ListBox1.Items.RemoveAt(i)
ListBox1.Items.Insert(i, j)
ListBox1.SelectedIndex = i
That works. Now as soon as the Object is changed the new value displays.
But I can't say I like it.
Isn't there a better way?
Thanks for any help
PS The ListBox appears to generate a list of strings so that it does not
have to access the objects when a Paint is required? Is that your
understanding?

I think that if the Object implements INotifyPropertyChanged that will
fix it. If you Google for that you can find some examples of how to
use it.

I have no idea about the Paint questions.
Hmm, just tried a few things to no avail, and then tried the
INotifyPropertyChanged interface you mentioned, but no dice. I
unfortunately don't know of a way to force a complete refresh without
reloading the effected item(s).

Here's the code I used if anyone wants to build on my efforts (just
paste into a new form's codebehind)

/////////////////////
Imports System.ComponentModel

Public Class Form1

Private listBox As ListBox
Private button As Button

Private listBoxItems As List(Of ListBoxItem)

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'// Load the ListBox
listBox = New ListBox()
Controls.Add(listBox)

'// Add an event to track if the values change
AddHandler listBox.SelectedIndexChanged, AddressOf
listBox_SelectedIndexChanged

'// Add some custom items to our listBoxItems
listBoxItems = New List(Of ListBoxItem)

For i As Integer = 0 To 9
listBoxItems.Add(New ListBoxItem(String.Format("Item {0}",
i.ToString()), i))
Next

'// Add them to our ListBox
listBox.Items.AddRange(listBoxItems.ToArray())

'// Load the Button
button = New Button()
button.Text = "Click Me"
button.Location = New Point(150, 10)
Controls.Add(button)

'// Map the Button's click event
AddHandler button.Click, AddressOf button_Click
End Sub

Private Sub listBox_SelectedIndexChanged(ByVal sender As Object,
ByVal e As EventArgs)
Dim item As ListBoxItem = DirectCast(listBox.SelectedItem,
ListBoxItem)
MessageBox.Show(String.Format("{0}, {1}", item.Text,
item.Value))
End Sub

Private Sub button_Click(ByVal sender As Object, ByVal e As
EventArgs)
'// Modify the listBoxItems
For Each item As ListBoxItem In listBoxItems
item.Value += 1
item.Text = String.Format("Item {0}",
item.Value.ToString())
Next

listBox.Update()
End Sub

End Class

Public Class ListBoxItem
Implements INotifyPropertyChanged

Public Sub New(ByVal text As String, ByVal value As Integer)
Me.Text = text
Me.Value = value
End Sub

Public Overrides Function ToString() As String
Return Text
End Function

Public Property Value() As Integer
Get
Return _Value
End Get
Set(ByVal value As Integer)
_Value = value

RaiseEvent PropertyChanged(Me, New
PropertyChangedEventArgs("Value"))
End Set
End Property
Private _Value As Integer = 0

Public Property Text() As String
Get
Return _Text
End Get
Set(ByVal value As String)
_Text = value

RaiseEvent PropertyChanged(Me, New
PropertyChangedEventArgs("Text"))
End Set
End Property
Private _Text As String = String.Empty

Public Event PropertyChanged(ByVal sender As Object, ByVal e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.Prope rtyChanged
End Class
/////////////////////

Thanks,

Seth Rowe

Nov 2 '07 #5
I was able to take your example and a slightly different approach and get the
behavior you were looking for. Instead of using a list, I used a
BindlingList and instead of listBox.Items.AddRange(listBoxItems.ToArray())
I had
listBox.DataSource = listBoxItems
The difference (I think) is that the BindingList looks for the
PropertyChanged event and raises a 'ListChanged' event, that the ListBox
looks for.
One thing that happened that I don't understand was that when the button was
clicked, and the items were changed, the SelectedIndexChanged event was
fired! And on the second change (second item in the list) the event was
fired, but the selecteditem was 'Nothing'. I had to comment out the code in
the routine to get it to work.

--
Terry
"rowe_newsgroups" wrote:
On Nov 2, 10:19 am, Jack Jackson <jacknos...@pebbleridge.comwrote:
On Fri, 2 Nov 2007 09:39:52 -0400, "Academia"

<academiaNOS...@a-znet.comwrote:
>(If you've seen this in the drawing NG, sorry. I inadvertently sent it
>there.)
>I have a listbox populated with Objects.
>The Class has a String field that ToString returns.
>I assume that is what the ListBox uses for its display. Correct?
>If I change the value of the object's string field the ListBox display does
>not change. Would you expect it to change?
>The Debugger shows that the item does in fact have the new value even though
>the display has not changed.
>I tried putting
>ListBox1.SuspendLayout() and ListBox1.ResumeLayout() around the change code
>to see it by chance that would trigger a change in display but it didn't. I
>didn't really expect it would.
>So I added code to remove and then add the item:
>Dim j As Object = ListBox1.Items(ListBox1.SelectedIndex)
>Dim i As Integer = ListBox1.SelectedIndex
>ListBox1.Items.RemoveAt(i)
>ListBox1.Items.Insert(i, j)
>ListBox1.SelectedIndex = i
>That works. Now as soon as the Object is changed the new value displays.
>But I can't say I like it.
>Isn't there a better way?
>Thanks for any help
>PS The ListBox appears to generate a list of strings so that it does not
>have to access the objects when a Paint is required? Is that your
>understanding?
I think that if the Object implements INotifyPropertyChanged that will
fix it. If you Google for that you can find some examples of how to
use it.

I have no idea about the Paint questions.

Hmm, just tried a few things to no avail, and then tried the
INotifyPropertyChanged interface you mentioned, but no dice. I
unfortunately don't know of a way to force a complete refresh without
reloading the effected item(s).

Here's the code I used if anyone wants to build on my efforts (just
paste into a new form's codebehind)

/////////////////////
Imports System.ComponentModel

Public Class Form1

Private listBox As ListBox
Private button As Button

Private listBoxItems As List(Of ListBoxItem)

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'// Load the ListBox
listBox = New ListBox()
Controls.Add(listBox)

'// Add an event to track if the values change
AddHandler listBox.SelectedIndexChanged, AddressOf
listBox_SelectedIndexChanged

'// Add some custom items to our listBoxItems
listBoxItems = New List(Of ListBoxItem)

For i As Integer = 0 To 9
listBoxItems.Add(New ListBoxItem(String.Format("Item {0}",
i.ToString()), i))
Next

'// Add them to our ListBox
listBox.Items.AddRange(listBoxItems.ToArray())

'// Load the Button
button = New Button()
button.Text = "Click Me"
button.Location = New Point(150, 10)
Controls.Add(button)

'// Map the Button's click event
AddHandler button.Click, AddressOf button_Click
End Sub

Private Sub listBox_SelectedIndexChanged(ByVal sender As Object,
ByVal e As EventArgs)
Dim item As ListBoxItem = DirectCast(listBox.SelectedItem,
ListBoxItem)
MessageBox.Show(String.Format("{0}, {1}", item.Text,
item.Value))
End Sub

Private Sub button_Click(ByVal sender As Object, ByVal e As
EventArgs)
'// Modify the listBoxItems
For Each item As ListBoxItem In listBoxItems
item.Value += 1
item.Text = String.Format("Item {0}",
item.Value.ToString())
Next

listBox.Update()
End Sub

End Class

Public Class ListBoxItem
Implements INotifyPropertyChanged

Public Sub New(ByVal text As String, ByVal value As Integer)
Me.Text = text
Me.Value = value
End Sub

Public Overrides Function ToString() As String
Return Text
End Function

Public Property Value() As Integer
Get
Return _Value
End Get
Set(ByVal value As Integer)
_Value = value

RaiseEvent PropertyChanged(Me, New
PropertyChangedEventArgs("Value"))
End Set
End Property
Private _Value As Integer = 0

Public Property Text() As String
Get
Return _Text
End Get
Set(ByVal value As String)
_Text = value

RaiseEvent PropertyChanged(Me, New
PropertyChangedEventArgs("Text"))
End Set
End Property
Private _Text As String = String.Empty

Public Event PropertyChanged(ByVal sender As Object, ByVal e As
System.ComponentModel.PropertyChangedEventArgs) Implements
System.ComponentModel.INotifyPropertyChanged.Prope rtyChanged
End Class
/////////////////////

Thanks,

Seth Rowe

Nov 2 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Fieldmedic | last post: by
1 post views Thread by Annette Massie | last post: by
3 posts views Thread by gdbjohnson-AT-yahoo-dot-ca-nospamplz | last post: by
8 posts views Thread by Oddball | last post: by
2 posts views Thread by Lloyd Sheen | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.