views:

29

answers:

1

I need to bind a textblock.text property to a single element in an observable collection, or array element, and have the text update using the INotifyPropertyChanged or INotifyCollectionChanged, whichever is best.

Most examples describe ways to bind listboxes or other list views to entire collections, but my application needs to update several textblocks on a screen depending on notification of a change in one or more elements of an array.

textblock1.Text = MyArray(0)... textblock2.Text = MyArray(1)... textblock3.Text = MyArray(2)... textblock4.Text = MyArray(3)... etc...

Is it possible to bind a single textblock to a single array element?

Is it possible to get notification of the proper type that will update one or more of the textblocks if any assigned element changes?

+1  A: 

All things are possible in WPF, one way or the other (or, usually, both, plus a bunch more).

The easy part first - if you've properly implemented INotifyPropertyChanged on the object in your array, bindings should update properly. INotifyCollectionChanged notifies you if elements in a collection have changed (i.e. been added/deleted).

It sounds like you are trying to update an unknown number (or even a known number, it doesn't really matter) of TextBlocks. Likely, the best way to do that is to use some kind of ItemsControl (ListBox is one) with an ItemsTemplate, and optionally the ItemsPanel. This will be the easiest way to maintain, in case the definition of the collection changes.

For instance, here is one ItemsControl example.

<ItemsControl x:Name="itemsExample"
              ItemsSource="{Binding MyCollection}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel HorizontalAlignment="Stretch" IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding SomeStringProperty}" Grid.Column="0" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

If, however, you really do want to bind individual TextBlocks, one way you can do it by implementing IValueConverter. You would then bind each of your TextBlocks to the collection, and use a ConverterParameter with the appropriate index. The converter would then just return the value of a string at that index.

<TextBlock Text="{Binding MyCollection,
                          Converter={StaticResource myObjectConverter},
                          ConverterParameter=0}" />

If you are using MVVM, another possibility is to have properties for each of the elements of your array, and bind to those properties. However, if you are doing that, I would question the need for the array in the first place.

Wonko the Sane
We use the array to provide a dynamic data source consisting of data read in from a flat-file upon application startup. The object providing this array data is a custom .dll, and we wrote our own events to notify when an element changes values. When this custom event fires, it triggers an event handler in the code-behind of our WPF project.
MBunds
It would be so much easier to be able to bind "SomeTextBlock.text" to "SomeArray(index)" using the proper interface.
MBunds
What do you mean, the "proper interface"?
Wonko the Sane
If you want to "bind" the text in the code-behind (almost verbatim to what you posted in your comment), you certainly can. It's not very "WPF'y" but it would work.
Wonko the Sane