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.
You're looking for MultiBinding
.
Your XAML
will look something like this:
<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
.
Create a converter that implements IMultiValueConverter. It might look something like this:
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.
<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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With