使用 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();
}
基于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();
}