現在、任意の数値を受け入れる 2 つのテキスト ボックスがあります。入力された 2 つの数値を取得して平均を計算するテキスト ブロックがあります。
このテキスト ブロックを両方のテキスト ボックスにバインドし、カスタム コンバーターを使用して平均を計算する方法があるかどうか疑問に思っていました。現在、両方のテキスト ボックスでテキスト変更イベントをキャッチし、その方法で平均を計算していますが、データ バインディングの方が効率的で簡単であると想定しています。
を探していMultiBinding
ます。
あなたXAML
は次のようになります:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="myFirst.Value" />
<Binding Path="mySecond.Value" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
myConverter
、myFirst.Value
、およびの適切な置換を使用しmySecond.Value
ます。
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
}
複数値コンバーターは、バインディングごとに 1 つのオブジェクト配列を受け取ります。double や int などを意図しているかどうかに応じて、必要に応じてこれらを処理できます。
2 つのテキスト ボックスがデータバインドされている場合は、テキスト ブロックのマルチバインディングで同じバインディングを使用するか (平均が更新されるようにプロパティが変更されたときに通知することを忘れないでください)、または 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>
または、コード ビハインドでプロパティを作成し、それに TextBlock をバインドすることもできます。私はいつもそうしていますが、コンバーターを作成して同じコードをそこで実行するよりも少し簡単です。
例: (xaml の背後にあるコード内):
public double AvgValue
{
get { return (valueA + valueB) / 2.0; }
}
次に、XAML で次のようにします。
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=AvgValue}" />
これは、カスタム コンバーターよりもはるかに簡単です。
ティモシーの答えに段階的な手順を追加するだけです: