Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Converter not called when Collection changes?

I made a CollectionToStringConverter which can convert any IList into a comma-delimited string (e.g. "Item1, Item2, Item3").

I use it like this:

<TextBlock Text="{Binding Items, 
                  Converter={StaticResource CollectionToStringConverter}}" />

The above works, but only once when I load the UI. Items is an ObservableCollection. The text block does not update, and the converter does not get called when I add or remove from Items.

Any idea what's missing to make this work?

like image 257
Anthony Brien Avatar asked Apr 24 '09 19:04

Anthony Brien


1 Answers

The binding is to the property yielding the collection. It will come into effect whenever the collection instance itself changes, not when items in the collection are changed.

There are quite a few ways to achieve the behavior you want, including:

1) Bind an ItemsControl to the collection and configure the ItemTemplate to output the text preceded by a comma if it's not the last item in the collection. Something like:

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <TextBlock>
            <TextBlock Visibility="{Binding RelativeSource={RelativeSource PreviousData}, Converter={StaticResource PreviousDataConverter}}" Text=", "/>
            <TextBlock Text="{Binding .}"/>
        </TextBlock>
    </ItemsControl.ItemTemplate>    
</ItemsControl>

2) Write code in your code-behind to watch the collection for changes and update a separate property that concatenates the items into a single string. Something like:

public ctor()
{
    _items = new ObservableCollection<string>();

    _items.CollectionChanged += delegate
    {
        UpdateDisplayString();
    };
}

private void UpdateDisplayString()
{
    var sb = new StringBuilder();

    //do concatentation

    DisplayString = sb.ToString();
}

3) Write your own ObservableCollection<T> subclass that maintains a separate concatenated string similar to #2.

like image 167
Kent Boogaart Avatar answered Sep 28 '22 01:09

Kent Boogaart