Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

WPF / Silverlight Quick Tip: INotifyPropertyChanged for indexer

Pete Brown - 08 March 2010

WPF and Silverlight allow you to bind to property indexers by string key or numeric index. For example:

<TextBox Text="{Binding [field1], Mode=TwoWay}" />
<TextBox Text="{Binding Fields[field1], Mode=TwoWay}" />
<TextBox Text="{Binding [15], Mode=TwoWay}" />

If you're creating the data source for those (for example, you are building your own ObservableDictionary), you may wonder how on earth you fire the appropriate INotifyPropertyChanged.PropertyChanged event to let the binding system know that the item with that field name or index has changed.

The binding system is looking for a property named "Item[]", defined by the constant string Binding.IndexerName. In your own setter, the notify would look something like this:

public string this[string key]
{
    get { return _items[key]; }
    set
    {
        _items[key] = value;

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(Binding.IndexerName);
    }
}

The case of "Item[]" is important; if you change the case, the binding system won't recognize it. Use the constant string.

Updated 2010-03-10: A commenter pointed out (thanks Oleg!) that there's a constant for this. Binding.IndexerName. I've updated the code example above to reflect that.

       
posted by Pete Brown on Monday, March 08, 2010
filed under:        

15 comments for “WPF / Silverlight Quick Tip: INotifyPropertyChanged for indexer”

  1. Tom McKearneysays:
    I haven't tested this, but does this only notify to bindings of this particular key, or does it fire for every element in the Item[] collection? It seems like it would cause all references to Item[] to update, which could be problematic for some
  2. Petesays:
    @Steve

    Correct.

    @Oleg

    You just totally sucked the fun out of the room. Where has all the magic gone? :)

    (Thanks. Always better to use the constant, I just didn't even bother to look for one. I'll update the blog post with it)

    Pete
  3. GAsays:
    Hi,

    Great post.

    Using SL4 RTM with VS 2010 RTM, the line below produces an error stating it cannot find "IndexerName" property. Is this only available in WPF?

    Binding.IndexerName
  4. Petesays:
    @GA

    Thanks.

    Looks like that's the case. Use the string "Item[]" instead. I originally had that in the sample, but someone pointed out Binding.IndexerName as a better practice. Forgot to re-test in Silverlight.

    Pete
  5. Bradsays:
    Try using "Item[" + key + "]" to avoid getting hammered by binding when using the broader "Item[]".

    However, "Item[]" is a convenient property name to fire an event with to get all item-based properties in one go.
  6. Bradsays:
    @Pete

    I'm using SL 4.0.50917.0 (release 28 Sep 2010) and works as I mentioned. I haven't tried it with WPF.

    I setup a view using four properties bound using the item indexer method. From the model side, I push a value into "Name" and fire "Item[]", all four properties get read. I repeat and fire "Item[Name]", only "Name" is read.
  7. Cameron Peterssays:
    @Brad --

    Unfortunately I can't get "Item[PropName]" to work with WPF. Any hints on how to make it work? Or perhaps this feature is not yet supported on WPF stack...

Comment on this Post

Remember me