Unable to cast object in WPF MultiValueConverter

1.1k Views Asked by At

I am trying to learn MultiBinding. I try to pass two values (one double and one boolean) from viewmodel to the converter and return a string result back.

XAML

<TextBlock>
     <TextBlock.Text>
         <MultiBinding Converter="{StaticResource MyValueConverter}">
              <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.PowerValue" />
              <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.IsPowerAvailable" />
         </MultiBinding>
     </TextBlock.Text>
</TextBlock>

Converter

class MyValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (System.Convert.ToBoolean(values[1]))
        {
            return string.Format("{0:n1}", values[0]); 
        }
        else
        {
            return "[not available]";
        }
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Viewmodel

public double PowerValue
public bool IsPowerAvailable

In the converter I will get an exception Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.IConvertible.

What does this mean? Did I implement the MultiBinding incorrectly?

EDIT:

ViewModel looks like this

class CarViewModel : ViewModelBase
{
    private car _selectedCar;
    public car SelectedCar
    {
        get { return _selectedCar; }
        set
        {
            _selectedCar = value;
        }
    }

Model looks like this:

class car 
{
    public double PowerValue { get; set; }
    public bool IsPowerAvailable{ get; set; }
}
1

There are 1 best solutions below

11
On BEST ANSWER

The exception is due to the fact that the DataContext.SelectedCar.IsPowerAvailable can't be reached, make sure that the SelectedCar property is indeed reachable from the ScrollViewer DataContext, here a working sample

 Title="MainWindow" Height="350" Width="525" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
    <wpfApplication12:MyValueConverter x:Key="MyValueConverter"/>
</Window.Resources>
<Grid>      
  <ScrollViewer>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource MyValueConverter}">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.PowerValue" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.IsPowerAvailable" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </ScrollViewer>
</Grid>

and the selectedCar is defined in the VM/CodeBhind:

private Car _selectedCar = new Car()
    {
        IsPowerAvailable = true,
        PowerValue = 14
    };
    public Car SelectedCar
    {
        get
        {
            return _selectedCar;
        }

        set
        {
            if (_selectedCar == value)
            {
                return;
            }

            _selectedCar = value;                
        }
    }