2013-12-18 4 views
0

Я использую IValueConverter для преобразования double в строку. Строка, созданная конвертером, не отображается в соответствующем текстовом поле. Например, если пользователь вводит 1.1, мой конвертер значений может форматировать его как «1». Однако я все еще вижу «1.1» в текстовом поле. Я проверил в отладчике, что метод Convert() конвертера вызывается и возвращает значение «1». Я что-то пропустил?IValueConverter не обновляет wpf TextBox

метод преобразователя заключается в следующем:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    if (value == null) 
    { 
     return string.Empty; 
    } 
    if (value is double && targetType == typeof(string)) 
    { 
     string format = parameter == null ? "{0:F2}" : (string)parameter; 
     string formatted = string.Format(format, value); 
     return formatted; 
    } 
    return value.ToString(); 
} 

Часть XAML выглядит следующим образом:

<TextBox x:Name="balance" Grid.Row="12" Grid.Column="1" 
Text="{Binding Balance, Converter={StaticResource nullableConverter}, ConverterParameter=\{0:F0 \}, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" Width="90" TextAlignment="Right" /> 

Спасибо.

+0

Вы видите ошибки привязки в окне вывода во время выполнения? –

+0

Нет, я не вижу никаких ошибок. – bdristan

+0

Итак, вы вводите «1.1», выходите из текстового поля, чтобы вызвать «UpdateSourceTrigger = PropertyChanged», свойство «Balance» в ваших обновлениях DataContext до «1.1», код конвертера запускается и преобразует '1.1' в' 1' , а затем TextBox.Text по-прежнему отображает '1.1'? Это не должно быть так ... можете ли вы проверить эти точные шаги в указанном порядке? – Rachel

ответ

0

Ваш элемент форматирования (материал внутри фигурных скобок) искажен.

Вместо

ConverterParameter=\{0:F0 \} 

Попробуйте

ConverterParameter='{}{0:F0} ' 

Однако, интересно, если установка Binding.StringFormat свойство не будет достаточно? Преобразование будет обработано для вас (вперед и назад), и вы тоже будете работать с валидацией (по крайней мере, для случая, когда пользователь вводит текст без номера).

+0

Синтаксис параметра кажется ОК, потому что я вижу его в методе Convert(), как и ожидалось. Кроме того, форматированная строка результата в методе верна. – bdristan

0

Сделайте привязку двумя способами, чтобы она протекала в обоих направлениях.

+0

По умолчанию привязка TwoWay для TextBox.Text' – Rachel

+0

Я считаю, что по умолчанию это два пути. Я сделал это двумя способами, но это не имело никакого значения. – bdristan

0

Он будет запускать этот конвертер, когда объект Binding распознает, что свойство «Balance» вашего ViewModel изменилось.

Есть ли у вашей модели ViewModel как публичный Getter, так и Setter?

Если это так, Binding должен вызывать свойство setter на ViewModel по мере изменения данных в текстовом поле.

Затем вам нужно вернуть сигнал к представлению (и привязке), который изменил значение свойства. Использует ли ваша модель просмотра INotifyPropertyChanged? Создана ли ваша модель просмотра событий PropertyChanged (с именем свойства «Баланс») при вызове средства настройки баланса?

1

Я считаю, что это известная проблема с помощью преобразователя на TextBox.Text когда UpdateSourceTrigger=PropertyChanged

Это, как правило, не является идеальным решением, так как типы пользователей, значение преобразуется, так как это может привести к путанице и неожиданные результаты для пользователя.

Например, если пользователь «1.1», и значение продолжает получать обрезается до «1» после каждого нажатия клавиши, последовательность событий будет:

  • типа
  • тип .
  • преобразователя изменения значения в 1
  • типа
  • значение теперь 11

В качестве обходного пути, я обычно рекомендую применять только форматирование, когда TextBox не имеет фокус с помощью триггера, например:

<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="Text" Value="{Binding Balance, Converter={StaticResource nullableConverter}, ConverterParameter=\{0:F0 \}" /> 

    <Style.Triggers> 
     <Trigger Property="IsKeyboardFocusWithin" Value="True"> 
      <Setter Property="Text" Value="{Binding Balance, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" /> 
     </Trigger> 
    </Style.Triggers> 
</Style> 
Смежные вопросы