Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind an element to two sources

Tags:

binding

wpf

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.

like image 215
Nick Avatar asked Nov 04 '08 00:11

Nick


2 Answers

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.

like image 85
Jacob Carpenter Avatar answered Nov 04 '22 22:11

Jacob Carpenter


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> 
like image 35
Donnelle Avatar answered Nov 04 '22 23:11

Donnelle