У меня есть текстовое поле, свойство 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 "либо не работают, либо вызывают другие проблемы.
Любая помощь будет принята с благодарностью.
Код ниже.
<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
}