Текст в TextBox с UpdateSourceTrigger = PropertyChanged не обновляется, когда принуждение ввода текста приводит к неизменному исходному значению

У меня есть текстовое поле, свойство Text которого имеет TwoWay MultiBinding с ] UpdateSourceTrigger установлен на PropertyChanged . Первая привязка связана со свойством зависимости ( Value ), которое имеет функцию PropertyChangedCallBack , которая округляет значение до одного десятичного знака.

Назначение текстовое поле предназначено для округления по мере того, как пользователь вводит текст, а не когда текстовое поле теряет фокус, поэтому для UpdateSourceTrigger установлено значение PropertyChanged .

Проблема, с которой я столкнулся, заключается в том, что если вводится текст, который НЕ приводит к изменению значения , свойство текст и значение не синхронизируются. Только если операция округления вызывает изменение значения , текст обновляется на лету. Например, если Текст и Значение оба равны 123,4 и пользователь вводит 1 после этого, Значение округляется до того же значения (123,4), но Текст показывает 123,41. Однако, если 9 затем набирается после 4, Значение округляется до 123,5. И из-за этого фактического изменения Текст затем обновляется до того же (123,5).

Есть ли способ принудительно обновить текстовое поле из его источника, даже если источник не изменился с тех пор последний триггер? Я пробовал использовать BindingExpressionBase.UpdateTarget () , но это работает, только если для UpdateSourceTrigger установлено значение Explicit , которое нельзя использовать как Value больше не обновляется до подходящего момента, когда может быть вызван UpdateTarget (например, обработчик TextInput ). Я пробовал другие методы, такие как явное обновление значения Text из связанного Value , принудительное фактическое изменение значения Value временно для вызова обновления, но эти " hacks "либо не работают, либо вызывают другие проблемы.

Любая помощь будет принята с благодарностью.

Код ниже.

Фрагмент 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
}
13
задан Neo 21 September 2016 в 15:59
поделиться