RoboDave
RoboDave

Reputation: 149

INotifyPropertyChanged Implemented now what?

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

Answers (2)

asktomsk
asktomsk

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

FMM
FMM

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

Related Questions