Bind an element to two sources
Solution 1:
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
.
Solution 2:
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>
Solution 3:
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.
Example: (in your code behind of the xaml):
public double AvgValue
{
get { return (valueA + valueB) / 2.0; }
}
And then, in your XAML:
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AvgValue}" />
That's a LOT simpler than a custom converter.