1

Based on this previously answered question, I'm trying to create an IMultiValueConverter that will allow the Text property of a TextBox in WPF to be bound to the sum of several other TextBox values. I've mirrored the answer to the referenced question fairly strictly, yet when testing this I get an InvalidCastException. In the code below, the lines commented out are the code from the aforementioned answer. I did try running this with the var datatype instead of using double (I dislike var, just a preference), and received the same error in the same place. I've tried changing the style of cast in various ways, including Convert.ToInt32, (int), and even int.Parse, but everything results in the same error, same location.

Does anybody have a clue as to what the problem with this could be? This is my first real foray into binding like this, so it could be I'm fundamentally misunderstanding it, but honestly don't think that's what it is...

public class AddListRecordsConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        double result = 0.0;

        try
        {
            double[] doubleValues = values.Cast<double>().ToArray();

            foreach (var doubleValue in doubleValues)
            {
                result += doubleValue;
            }

            //var doubleValues = values.Cast<double>().ToArray();
            //var leftPart = string.Join(" x ", doubleValues);
            //var rightPart = doubleValues.Sum().ToString();
            //var result = string.Format("{0} = {1}", leftPart, rightPart);
            //return result;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

        return result;
    }

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

Destination TextBox:

<TextBox x:Name="allRecords"  Style="{StaticResource dataEntryTextBox}" Grid.Column="1" Grid.Row="6">
                        <TextBox.Text>
                            <MultiBinding Converter="{StaticResource AddListRecordsConverter}">
                                <Binding ElementName="allRecordsOne" Path="Text"></Binding>
                                <Binding ElementName="allRecordsTwo" Path="Text"></Binding>
                            </MultiBinding>
                        </TextBox.Text>
                    </TextBox>

Source TextBoxes:

<TextBox x:Name="allRecordsOne"  Style="{StaticResource dataEntryTextBox}" Grid.Column="0" Grid.Row="4" GotFocus="SelectAllOnFocus_GotFocus" LostFocus="allRecords_LostFocus" />
<TextBox x:Name="allRecordsTwo"  Style="{StaticResource readOnlyTextBox}" Grid.Column="0" Grid.Row="5" Text="{Binding ElementName=allRecordsOne, Path=Text}" GotFocus="SelectAllOnFocus_GotFocus" LostFocus="allRecords_LostFocus" />
<TextBox x:Name="allRecordsThree"  Style="{StaticResource readOnlyTextBox}" Grid.Column="0" Grid.Row="6" Text="{Binding ElementName=allRecordsOne, Path=Text}" GotFocus="SelectAllOnFocus_GotFocus" LostFocus="allRecords_LostFocus" />
Community
  • 1
  • 1
Keven M
  • 972
  • 17
  • 47
  • I was thinking that as long as the logic was non-specific it would stil technically be MVVM. Granted I'm not very clear on MVVM, but since this is generic wouldn't it still qualify? For example, were I to use a reference to allRecords.Text in the Converter method, I could see it as violating MVVM, but because this converter can be used by any random textbox, it should still work right? – Keven M May 08 '16 at 18:50
  • Well, I'm not sure, but I don't think so. The reason for the summing (actually subtraction now, but same concept) is that there's a number that increments each day. There are 3 portions of the total time that need to be recorded. This is done by subtracting the value at 10am from the value at 12pm. The system won't ever change but if it changed to something besides a textbox, the binding would just need to be moved to the new control. I could just be missing the MVVM portion of this, I don't get how MVVM works very well, and haven't found a good explanation yet to help understand it :) – Keven M May 08 '16 at 19:23

1 Answers1

4

I simplified your example. Note that I used Mode="OneWay" to avoid exception in ConvertBack method.

<StackPanel>
    <TextBox x:Name="allRecords">
        <TextBox.Text>
            <MultiBinding Converter="{StaticResource AddListRecordsConverter}">
                <Binding ElementName="allRecordsOne" Path="Text" Mode="OneWay"/>
                <Binding ElementName="allRecordsTwo" Path="Text" Mode="OneWay"/>
            </MultiBinding>
        </TextBox.Text>
    </TextBox>

    <TextBox x:Name="allRecordsOne" />
    <TextBox x:Name="allRecordsTwo" />
</StackPanel>

the issue with the converter is that it receives two empty strings (default value of text) as input (values) and can't handle them properly. it has to be more defensive

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    double val = 0.0;
    double result = 0.0;

    foreach (var txt in values)
    {
        if (double.TryParse(txt.ToString(), out val))
            result += val;
        else
            return "NaN";
    }

    return result.ToString();
}
ASh
  • 34,632
  • 9
  • 60
  • 82