39

我目前有两个接受任何数字的文本框。我有一个文本块,它接受输入的两个数字并计算平均值。

我想知道是否有一种方法可以将此文本块绑定到两个文本框并使用自定义转换器来计算平均值?我目前正在两个文本框中捕获文本更改事件并以这种方式计算平均值,但我假设数据绑定会更有效和更容易。

4

4 回答 4

56

你正在寻找MultiBinding.

你的XAML会看起来像这样:

<TextBlock>
  <TextBlock.Text>
    <MultiBinding Converter="{StaticResource myConverter}">
      <Binding Path="myFirst.Value" />
      <Binding Path="mySecond.Value" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

合理替换myConverter,myFirst.ValuemySecond.Value.

于 2008-11-04T00:30:20.257 回答
37

创建一个实现 IMultiValueConverter 的转换器。它可能看起来像这样:

class AverageConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int total = 0;
        int number = 0;
        foreach (object o in values)
        {
            int i;
            bool parsed = int.TryParse(o.ToString(), out i);
            if (parsed)
            {
                total += i;
                number++;
            }
        }
        if (number == 0) return 0;
        return (total/number).ToString();
    }

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

    #endregion
}

多值转换器接收一个对象数组,每个绑定一个对象数组。您可以根据需要处理这些,具体取决于您是否打算将其用于 double 或 int 或其他。

如果这两个文本框是数据绑定的,您可以在文本块的多重绑定中使用相同的绑定(请记住在属性更改时通知以便更新平均值),或者您可以通过 ElementName 引用文本框来获取文本值。

<TextBox Text="{Binding Value1}" x:Name="TextBox1" />
<TextBox Text="{Binding Value2}" x:Name="TextBox2" />

<TextBlock>
   <TextBlock.Text>
      <MultiBinding Converter="{StaticResource AverageConverter}">
         <Binding ElementName="TextBox1" Path="Text" />
         <Binding ElementName="TextBox2" Path="Text" />
         <!--  OR  -->
         <!-- <Binding Path="Value1" />  -->
         <!-- <Binding Path="Value2" />  -->

      </MultiBinding>
   </TextBlock.Text>
</TextBlock>
于 2008-11-04T00:55:32.810 回答
2

或者,您可以在后面的代码中创建一个属性,并将 TextBlock 绑定到该属性……我一直这样做,这比制作转换器要简单一些,然后在那里执行相同的代码。

示例:(在 xaml 后面的代码中):

public double AvgValue
{
    get { return (valueA + valueB) / 2.0; }
}

然后,在您的 XAML 中:

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AvgValue}" />

这比自定义转换器简单得多。

于 2008-11-04T00:59:56.547 回答
0

只是将分步程序添加到蒂莫西的答案中:

  1. 设置 View.TextBlock.Text 属性以绑定到 ViewModel.AvgValue 属性。
  2. 捕获 TextBox 控件的 TextChanged 事件,然后在该 TextChanged 事件的处理程序中设置 AvgValue。
  3. 作为步骤 2 中该处理程序的一部分,请确保引发属性更改,以便更新 TextBlock。
于 2012-12-05T19:42:44.500 回答