How to get a ListBox to automatically refresh entries using the item's ToString method?
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()
.
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.
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..??
精彩评论