Reputation: 149
I am trying to create a list box that displays a set of data that will be updated over time. I have a simple list box:
<ListBox Name="lbRegisters" ItemsSource="{Binding}" />
And I have defined a class for my objects:
public class register : INotifyPropertyChanged
{
private int address;
public int Address { get { return address; } }
private int value;
public int Value
{
get{ return value; }
set{
this.value = value;
OnValueChanged("Value");
}
}
public register(int a)
{
address = a;
value = 0;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnValueChanged(string name){
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public override string ToString()
{
return address + ": " + value;
}
}
And I hold a list of these in an ObservableCollection<register>. Then set the ListBox.ItemsSource=registerslist; in the CodeBehind. The list is initialized and the inital data displays correctly.
Now what do I need to do to get my ListBox to update when a "register.Value" changes. The event handler is called but there nothing is subscribed to the event.
I guess I need to trigger something in the ListBox or ObservableCollection to tell the GUI to update. I have read dozens of posts of a similar problem but they all seem to indicate that once you have implemented INotofyPropertyChanged it just automagicaly works.
What is the next step?
Upvotes: 1
Views: 312
Reputation: 2298
The problem is on your ToString()
function. Yes it could be used to display complex string in ListView items but it is not a proper way to bindings because ListView does not knows when part of this string was changed.
Do the following:
1. Declare property on register
class like
public string AddressValue
{
get { return address + ": " + value; }
}
2. Add OnValueChanged("AddressValue")
in value
and address
setters like:
public int Value
{
get{ return value; }
set{
this.value = value;
OnValueChanged("Value");
OnValueChanged("AddressValue")
}
}
3. Declare you ListBox with ItemTemplate like:
<ListBox x:Name="lbRegisters" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding AddressValue}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So the idea is adding new property to register
class which will be updated when address
and value
changed. And bind list item text to this property.
Upvotes: 3
Reputation: 4329
I think understand the spirit of what you're asking (even though it's obviously unfinished ATM). I'd recommend using something that inherits from DependencyObject
and using dependency properties. Use the propdp
snippet in Visual Studio. It will save you a ton of boilerplate code and wiring.
Upvotes: -1