I currently have two text boxes which accept any number. I have a text block that takes the two numbers entered and calculates the average.
我目前有两个文本框,可以接受任何数字。我有一个文本块,它接收输入的两个数字并计算平均值。
I was wondering if there was a way I could bind this text block to both text boxes and utilize a custom converter to calculate the average? I currently am catching the text changed events on both text boxes and calculating the average that way, but I am under the assumption data binding would be more efficient and easier.
我想知道是否有一种方法可以将这个文本块绑定到两个文本框并使用自定义转换器来计算平均值?我目前正在捕捉文本框上的文本更改事件,并以这种方式计算平均值,但我假定数据绑定将更有效、更容易。
4 个解决方案
#1
55
You're looking for MultiBinding
.
你正在寻找MultiBinding。
Your XAML
will look something like this:
你的XAML看起来像这样:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="myFirst.Value" />
<Binding Path="mySecond.Value" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
With reasonable replacements for myConverter
, myFirst.Value
, and mySecond.Value
.
与合理的替代myConverter, myFirst。值,mySecond.Value。
#2
34
Create a converter that implements IMultiValueConverter. It might look something like this:
创建一个实现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
}
A multivalue converter receives an object array, one for each of the bindings. You can process these however you need, depending on whether you're intending it for double or int or whatever.
多值转换器接收一个对象数组,每个绑定对应一个对象数组。你可以处理这些你需要的东西,这取决于你想要的是双还是整。
If the two textboxes are databound, you can use the same bindings in the multibinding for your textblock (remembering to notify when the property changes so that your average is updated), or you can get the text value by referring to the textboxes by ElementName.
如果这两个文本框是databound,那么您可以在multibinding中为您的textblock使用相同的绑定(记住在属性发生更改时通知,以便更新平均值),或者您可以通过引用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>
#3
2
Or, you could make a property in code behind, and bind the TextBlock to that ... I do that all the time, and it's a little simpler than making a converter, then doing that same code there.
或者,您可以在后面的代码中创建一个属性,并将TextBlock绑定到……我一直这么做,这比做一个转换器简单一点,然后在那里做同样的代码。
Example: (in your code behind of the xaml):
示例:(在xaml后面的代码中):
public double AvgValue
{
get { return (valueA + valueB) / 2.0; }
}
And then, in your XAML:
然后,在你的XAML中:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AvgValue}" />
That's a LOT simpler than a custom converter.
这比自定义转换器简单得多。
#4
0
Just to add step-by-step procedure to Timothy's answer:
让我们在提摩太的回答中加入一步一步的步骤:
- Setup the View.TextBlock.Text property to bind to the ViewModel.AvgValue property.
- 设置View.TextBlock。要绑定到ViewModel的文本属性。AvgValue财产。
- Catch the TextChanged event of the TextBox control, then set the AvgValue in the handler of that TextChanged event.
- 捕获TextBox控件的TextChanged事件,然后在该TextChanged事件的处理程序中设置AvgValue。
- As part of that handler in step 2, make sure to raise a property change so that the TextBlock is updated.
- 作为第2步处理程序的一部分,请确保引发属性更改,以便更新TextBlock。
#1
55
You're looking for MultiBinding
.
你正在寻找MultiBinding。
Your XAML
will look something like this:
你的XAML看起来像这样:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="myFirst.Value" />
<Binding Path="mySecond.Value" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
With reasonable replacements for myConverter
, myFirst.Value
, and mySecond.Value
.
与合理的替代myConverter, myFirst。值,mySecond.Value。
#2
34
Create a converter that implements IMultiValueConverter. It might look something like this:
创建一个实现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
}
A multivalue converter receives an object array, one for each of the bindings. You can process these however you need, depending on whether you're intending it for double or int or whatever.
多值转换器接收一个对象数组,每个绑定对应一个对象数组。你可以处理这些你需要的东西,这取决于你想要的是双还是整。
If the two textboxes are databound, you can use the same bindings in the multibinding for your textblock (remembering to notify when the property changes so that your average is updated), or you can get the text value by referring to the textboxes by ElementName.
如果这两个文本框是databound,那么您可以在multibinding中为您的textblock使用相同的绑定(记住在属性发生更改时通知,以便更新平均值),或者您可以通过引用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>
#3
2
Or, you could make a property in code behind, and bind the TextBlock to that ... I do that all the time, and it's a little simpler than making a converter, then doing that same code there.
或者,您可以在后面的代码中创建一个属性,并将TextBlock绑定到……我一直这么做,这比做一个转换器简单一点,然后在那里做同样的代码。
Example: (in your code behind of the xaml):
示例:(在xaml后面的代码中):
public double AvgValue
{
get { return (valueA + valueB) / 2.0; }
}
And then, in your XAML:
然后,在你的XAML中:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AvgValue}" />
That's a LOT simpler than a custom converter.
这比自定义转换器简单得多。
#4
0
Just to add step-by-step procedure to Timothy's answer:
让我们在提摩太的回答中加入一步一步的步骤:
- Setup the View.TextBlock.Text property to bind to the ViewModel.AvgValue property.
- 设置View.TextBlock。要绑定到ViewModel的文本属性。AvgValue财产。
- Catch the TextChanged event of the TextBox control, then set the AvgValue in the handler of that TextChanged event.
- 捕获TextBox控件的TextChanged事件,然后在该TextChanged事件的处理程序中设置AvgValue。
- As part of that handler in step 2, make sure to raise a property change so that the TextBlock is updated.
- 作为第2步处理程序的一部分,请确保引发属性更改,以便更新TextBlock。