L.E.O
L.E.O

Reputation: 1109

Indexer binding

This is probably a very stupid question, but I just cant figure it out. Assuming that I have a data structure represented by these two classes:

class Accessor
{
}


class Row : INotifyCollectionChanged
{
    public object this[Accessor index] {get;}
}

And if I also have a view-model like this:

class ViewModel
{
     public Row CurrentRow{get;}
     public Accessor CurrentAccessor {get;}
}

How can I define CurrentRow[CurrentAccessor] binding in XAML? I have tried using {Binding Path=CurrentRow[{Binding Path=CurrentAccessor}]}, but this doesn't seem to work.

Update: I should point out that Row class is a collection that implements INotifyCollectionChanged interface, so using a simple property wrapper like this
public object WrappedProperty { get{return CurrentRow[CurrentAccessor];}} wouldn't work since then there will be no updates if the values stored in CurrentRow[CurrentAccessor] changes.

Upvotes: 0

Views: 199

Answers (2)

Clemens
Clemens

Reputation: 128060

You might change your Binding into a MultiBinding with an appropriate converter:

<MultiBinding Converter="{StaticResource RowAccessorConverter}">
    <Binding Path="CurrentRow"/>
    <Binding Path="CurrentAccessor"/>
</MultiBinding>

The converter might look like this:

public class RowAccessorConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var row = values[0] as Row;
        var accessor = values[1] as Accessor;
        return row[accessor];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Upvotes: 2

kmatyaszek
kmatyaszek

Reputation: 19296

In ViewModel you can create additional property.

class ViewModel
{
     public object Obj { get { return CurrentRow[CurrentAccessor]; } }
     public Row CurrentRow{ get; }
     public Accessor CurrentAccessor { get; }
}

And binding now is simple:

{Binding Obj}

Upvotes: 2

Related Questions