Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a WPF binding distinguish between an indexer property and a list element?

I have a binding of the form:

Path=SpecialCollection[0]

The SpecialCollection class extends ObservableCollection and has an indexer property.

public T this[string propertyValue]
{
    get
    {
        // do stuff
        return default(T);
    }
}

My problem is that the binding attempts to get the indexer property value, instead of returning the 0th item in the collection. Is there a way to force the binding to treat 0 as an integer so it returns a collection element, instead of invoking the collection's indexer property's getter?

like image 445
Craig Avatar asked Apr 21 '11 01:04

Craig


2 Answers

According to MSDN you can tell the binding the type of the value entered as index:

Inside indexers you can have multiple indexer parameters separated by commas (,). The type of each parameter can be specified with parentheses. For example, you can have Path="[(sys:Int32)42,(sys:Int32)24]", where sys is mapped to the System namespace.

I noticed that the Binding constructor taking a path string uses another PropertyPath constructor than the default PropertyPath type converter, said PropertyPath constructor does not work in this scenario. To avoid the problem avoid the Binding constructor by setting the Path property manually which invokes the conversion via type converter.

<!-- Does not work -->
<TextBlock Text="{Binding [(sys:Int32)0]}"/>
<!-- Does work -->
<TextBlock Text="{Binding Path=[(sys:Int32)0]}"/>
like image 57
H.B. Avatar answered Oct 20 '22 00:10

H.B.


Actually you have two indexer properties, one that takes an int argument and one that takes a string argument. Frankly, I don't know how the binding expression chooses which indexer to use when it is ambiguous. If there is only one then it can coerce the index to the type of the indexer argument. If there are two, it can either throw an exception or choose one according to a heuristic. In this case, it apparently chose the wrong one.

To solve this problem you can either move your string indexer "down a level" so it hangs off of a new property so that it doesn't compete with the list indexer or if all you need is List[0] you can add a First property and bypass either indexer.

like image 25
Rick Sladkey Avatar answered Oct 20 '22 00:10

Rick Sladkey