views:

272

answers:

3

I have a class with an indexer property, with a string key:

public class IndexerProvider {
    public object this[string key] {
        get
        {
            return ...
        }
        set
        {
            ...
        }
    }

    ...
}

I bind to an instance of this class in WPF, using indexer notation:

<TextBox Text="{Binding [IndexerKeyThingy]}">

That works fine, but I want to raise a PropertyChanged event when one of the indexer values changes. I tried raising it with a property name of "[keyname]" (i.e. including [] around the name of the key), but that doesn't seem to work. I don't get binding errors in my output window whatsoever.

I can't use CollectionChangedEvent, because the index is not integer based. And technically, the object isn't a collection anyway.

Can I do this, and so, how?

+7  A: 

According to this blog entry, you have to use "Item[]". Item being the name of the property generated by the compiler when using an indexer.

If you want to be explicit, you can decorate the indexer property with an IndexerName attribute.

That would make the code look like:

public class IndexerProvider : INotifyPropertyChanged {

    [IndexerName ("Item")]
    public object this [string key] {
        get {
            return ...;
        }
        set {
            ... = value;
            FirePropertyChanged ("Item[]");
        }
    }
}

At least it makes the intent more clear. I don't suggest you change the indexer name though, if your buddy found the string "Item[]" hard coded, it probably means that WPF would not be able to deal with a different indexer name.

Jb Evain
That works great. Strange that I missed that blogpost in my Google searches.
Inferis
A: 

All I can say is WOW this works like a champ. thanks so much!

robmc
Is this an anwer? No. Comment comments, answer answers.
Dykam
A: 

Actually, I believe setting the IndexerName attribute to "Item" is redundant. The IndexerName attribute is specifically designed to rename an index, if you want to give it's collection item a different name. So your code could look something like this:

public class IndexerProvider : INotifyPropertyChanged {

    [IndexerName("myIndexItem")]
    public object this [string key] {
        get {
            return ...;
        }
        set {
            ... = value;
            FirePropertyChanged ("myIndexItem[]");
        }
    }
}

Once you set the indexer name to whatever you want, you can then use it in the FirePropertyChanged event.

dimondwoof