У меня есть текстовое поле, у которого Текстовое свойство имеет TwoWay MultiBinding с UpdateSourceTrigger с PropertyChanged. Первым связыванием является свойство зависимостей (Значение), которое имеет функцию PropertyChangedCallBack, которая округляет значение до одного десятичного знака.
Цель текстового поля - выполнять округление по типу пользователя, а не при том, что текстовое поле теряет фокус, поэтому для параметра UpdateSourceTrigger установлено значение PropertyChanged.
Проблема заключается в том, что если текст введен, который не приводит к изменению Значение, свойство Текст и Значение синхронизации. Только если операция округления вызывает изменение Значение, Текст обновляется "на лету". Например, если Текст и Значение равны 123.4, а пользовательский тип 1 после этого, Значение округляется до того же значения (123.4), но Текст показывает 123.41. Однако, если 9 после этого вводится после 4, Значение округляется до 123.5. И из-за этого фактического изменения Текст затем обновляется до того же (123.5).
Есть ли способ заставить текстовое поле обновляться из его источника, даже если источник не изменился со времени последнего триггера? Я попытался использовать BindingExpressionBase.UpdateTarget()
, но это работает только тогда, когда UpdateSourceTrigger установлено значение Явно, которое не может использоваться как Значение больше не получает обновлен до подходящего времени, когда можно было вызвать UpdateTarget (например, обработчик TextInput). Я пробовал другие методы, такие как явное обновление значения Текст из привязанного Значение, чтобы временно изменить значение Значение, чтобы вызвать обновление, но эти "хаки" либо не работают, либо вызывают другие проблемы.
Любая помощь будет принята с благодарностью.
Код ниже.
фрагмент 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>
фрагмент С#
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
}