TextプロパティにTwoWay MultiBindingがあり、 UpdateSourceTrigger がPropertyChangedに設定されているテキスト ボックスがあります。最初のBindingは、値を小数点以下 1 桁に丸めるPropertyChangedCallBack関数を持つ依存関係プロパティ ( Value )に対するものです。
テキスト ボックスの目的は、テキスト ボックスがフォーカスを失ったときではなく、ユーザーが入力したときに丸めを実行することです。そのため、 UpdateSourceTriggerがPropertyChangedに設定されています。
私が抱えている問題は、値が変更されないテキストが入力された場合、 Textプロパティと値が同期しなくなることです。丸め操作によってValueが変更された場合にのみ、 Textがその場で更新されます。たとえば、TextとValueが両方とも 123.4 で、ユーザーがこの後に 1 を入力した場合、Valueは同じ値 (123.4) に丸められますが、Textは 123.41 を示します。ただし、4 の後に 9 を入力すると、Valueは 123.5 に切り上げられます。この実際の変更により、Textは同じ (123.5) に更新されます。
ソースが最後のトリガーから変更されていない場合でも、テキスト ボックスをソースから強制的に更新する方法はありますか? 使用してみましたが、これはUpdateSourceTriggerがExplicitに設定されてBindingExpressionBase.UpdateTarget()
いる場合にのみ機能します。これは、 UpdateTargetを呼び出すことができる適切な時間 ( TextInputハンドラーなど)の前に値が更新されないため、使用できません。バインドされたValueからText値を明示的に更新する、一時的にValueを実際に変更して更新を呼び出すなどの他の方法を試しましたが、これらの「ハック」は機能しないか、他の問題を引き起こします。
どんな助けでも大歓迎です。
コードは以下です。
XAML スニペット
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{local:NumberFormatConverter}"
UpdateSourceTrigger="Explicit"
Mode="TwoWay">
<Binding Path="Value"
RelativeSource="{RelativeSource AncestorType={x:Type Window}}"
Mode="TwoWay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
C# スニペット
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value", typeof(decimal), typeof(MainWindow),
new FrameworkPropertyMetadata(0m,
new PropertyChangedCallback(OnValueChanged)));
private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
obj.SetValue(ValueProperty, Math.Round((decimal)args.NewValue, 1));
}
コンバータークラスが必要
public class NumberFormatConverter : MarkupExtension, IMultiValueConverter
{
public static NumberFormatConverter Instance { private set; get; }
static NumberFormatConverter()
{
Instance = new NumberFormatConverter();
}
public override object ProvideValue(IServiceProvider serviceProvider_)
{
return Instance;
}
#region Implementation of IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0].ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
var result = 0m;
if (value != null)
{
decimal.TryParse(value.ToString(), out result);
}
return new object[] { result };
}
#endregion
}