Xamarin Pass Parent BindingContext Value to Converter

Viewed 1304

I have a master list of selectable cars, and a second list containing the IDs of the selected cars.

public class SelectCarsViewModel : BindableBase 
{
    public IList<Car> Cars = new List<Car>();
    public IList<string> SelectedCars = new List<string>();
}

public class Car
{
    public string Id {get; set;}
}

I need to display a check mark next to every selected car. I'm trying to accomplish this by developing a converter which takes the ID of the current car, and the SelectedCars list. I'm having difficulty passing the SelectedCars list from XAML. I'm able to pass SelectCarsPage, but not its BindingContext nor its SelectedCars property.

<ContentPage x:Name="SelectCarsPage">
    <ListView ItemsSource=Cars>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Id, Converter={StaticResource IsCarSelected}, ConverterParameter={Binding Source={x:Reference Name=SelectCarsPage}, Path=SelectedCars}}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

public class IsCarSelected : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //parameter is SelectCarsPage and not the SelectedCars list.

        //I'd eventually like to get the following to work
        var selectedCars = (List<string>)parameter;
        return selectedCars.Contains(value.ToString()) ? "√" : "";
    }
}
4 Answers
<Label Text="{Binding Id, Converter={StaticResource IsCarSelected}, ConverterParameter={Binding Source={x:Reference Name=SelectCarsPage}, Path=BindingContext.SelectedCars}}"/>

When you perform a binding reference/source, you don't bind to the BindingContext but to the control itself. If you want to access to a property from its BindingContext (the view model), you have to set the path like this :

Path=BindingContext.SelectedCars

This kind of binding hits the control itself because it allows to get the value of properties such as the height, width, visibility and so on. If you need a property from its BindingContext, use the BindingContext object and then, target the property you need.

Good luck!

You can use like this

var source = (parameter as Binding).Source as ListView; if (source == null) return result;

var itemSource = source.ItemsSource as IList;

Related