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)

08 Mar 2010

WPF / Silverlight Quick Tip: INotifyPropertyChanged for indexer

       

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.

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

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

  1. Jobisays:
    Very helpful I came across this a lot but didnt have an idea.. Hope this is not a new addition to the framework.
  2. Mortensays:
    Sweet! Just what I needed. Been pondering on this one for a whlie.
  3. 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
  4. Petesays:
    Hey Tom.

    I suspected it may re-evaluate everything. Turns out we're right.

    http://10rem.net/blog/2010/03/09/tracing-wpf-in-visual-studio-2010

    Pete
  5. Stevesays:
    string indexers only work in Silverlight 4, and in Silverlight 3 you can only use int indexers on IList types.
  6. Olegsays:
    Hi,

    I'd like to add also that magic string "Item[]" is defined as a const string IndexerName in Binding class. I belive it makes it little less magic:)

    Oleg
  7. 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
  8. 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
  9. 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
  10. 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.
  11. Petesays:
    @Brad

    Thanks. Did you try that? As I recall, Using Item with the key either didn't work or had the same effect.

    Pete
  12. 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.
  13. Judah Gabriel Himangosays:
    Just wanted to confirm that Brad's suggestion of using "Item[PropName]" does indeed work for Silverlight 4. I'm doing something like this: RaisePropertyChanged("Item[" + property + "]") and the binding does indeed work.
  14. 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...
  15. Inquisitorsays:
    Thanks for the clarity. I replaced 500 lines of code with 5 thanks to this technique.

Comment on this Post

Remember me