使用 MultiBinding 计算多个文本框的总和

Using MultiBinding to calculate sum of multiple textboxes

基于this previously answered question,我正在尝试创建一个IMultiValueConverter,它将允许WPF 中的TextBox 的Text 属性 绑定到其他几个TextBox 的总和值。我已经相当严格地反映了所引用问题的答案,但是在测试时我得到了 InvalidCastException。在下面的代码中,注释掉的行是上述答案中的代码。我确实尝试 运行 使用 var 数据类型而不是使用 double(我不喜欢 var,只是一个偏好),并收到了 在同一个地方出现同样的错误。我尝试过以各种方式更改演员表的样式,包括 Convert.ToInt32(int),甚至 int.Parse,但所有结果都会导致相同的错误,相同的位置。

有人知道这可能是什么问题吗?这是我第一次真正尝试这样的绑定,所以我可能从根本上误解了它,但老实说,我不认为它是这样的...

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();
    }
}

目标文本框:

<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>

源文本框:

<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" />

我简化了你的例子。请注意,我使用 Mode="OneWay" 来避免 ConvertBack 方法中出现异常。

<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>

转换器的问题是它接收两个空字符串(文本的默认值)作为输入 (values) 并且无法正确处理它们。它必须更具防御性

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();
}