.netwpfmvvmrelaycommandimultivalueconverter

Using IMultiValueConverter to pass multiple CommandParameters to viewModel


I have the following code:

<DataGridTemplateColumn Header="Security">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Name="Security" Content="{Binding Path=totalSecurities}"
                    Command="{Binding Source={StaticResource viewModel}, Path=filterGridCommand}">
                <Button.CommandParameter>
                    <MultiBinding Converter="{StaticResource PassThroughConverter}">
                        <Binding Path="sector"/>
                        <Binding ElementName="Security" Path="Name"/>
                    </MultiBinding>
                </Button.CommandParameter>
            </Button>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Below is the code for PassThroughConverter:

public class PassThroughConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameters, CultureInfo culture)
    {
        return values;
    }

    public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

When I debug as soon as it hits the return values line, the correct values are in the array but when i press the button that triggers the filtergridcommand, the values returned are both null? Can anyone help. Thank you.


Solution

  • Some experimentation confirms that doing this

    public object Convert(object[] values, Type targetType, 
                          object parameters, CultureInfo culture)
    {
        return values;
    }
    

    results in the command parameter ending up as object[] { null, null }.

    The converter is run every time a bound value changes, not when the command is executed, and the return value is cached for use when the command is executed. The original parameter object[] values appears to be reset to all nulls.

    The solution is to clone the values parameter. In your case you can do this:

    public object Convert(object[] values, Type targetType, 
                          object parameter, CultureInfo culture)
    {
        return new [] {values[0], values[1]};
    }
    

    More usefully, a variable number of values can be handled like this:

    public object Convert(object[] values, Type targetType, 
                          object parameter, CultureInfo culture)
    {
        return values.ToArray();
    }