3

I've got a ListBox and an ObservableCollection<HostEntry>. HostEntry implements INotifyPropertyChanged. At present, I'm binding them this way:

        lstHosts.DataContext = _hosts;
        lstHosts.DisplayMemberPath = "HostName";

Which works great. When I edit one of the HostEntries' name, the ListBox gets refreshed automatically, showing the new name.

However, I'd rather have it display the HostEntry.ToString() as it does by default (not setting DiplayMemberPath, but if I do this, the list doesn't get refreshed. I believe this is because the HostName property fires a PropertyChanged event, but there's nothing to signal that ToString() has changed.

Is there perhaps something I can add to this method:

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

To inform the ListBox that it should refresh this item?

I don't like the idea of calling ListBox.Items.Refresh() explicitly... what if I miss a case, or whatever there are multiple views of this list? It also shouldn't be baked into the collection, because what if I want to use different collections of HostEntry? Should be a way to do it somewhere inside the HostEntry class, no?


Edit: I want to use ToString() because I don't simply want to display the HostName property. I want to do some string formatting with some other properties, which I can easily do in ToString().

2
  • can I ask why you dont want to use a property? what is the benefit of not setting the DisplayMemberPath property? Commented May 1, 2011 at 2:36
  • @Mark2: Because I don't want to display a simple property, I want to display a combination of properties. I need it to call a function so that I can combine them. Commented May 1, 2011 at 16:15

2 Answers 2

3

Databinding only works the way you want it to work with the ToString() method for immutable classes and structures. That is to say, to change the value of ToString() you would have to replace the entry in the observable collection which the list box is prepared to handle.

If you would like to simulate full support for ToString() with a mutable class I am afraid you will have to create a property, call for example AsString, and properly notify all changes for it when anything that could affect the value. This sort of defeats the point for your use case.

Sign up to request clarification or add additional context in comments.

Comments

1

Have you tried setting the ItemTemplate for the listbox instead of setting DisplatMemberPath like this -

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding HostName}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>

I guess this is what you want if am not wrong..??

2 Comments

Not quite. I wanted to use something a bit more complicated than binding it to a property. I want to use ToString() so that I combine some of the other properties into one display value.
For that case you can have a single property in your viewmodel to which you bind and just write your logic of combining different properties in its getter and make sure when u edit hostname u fire property change event for this property also..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.