Двухстороннее связывание WPF: как обновить TextBox отформатированной версией только что установленного значения?
У меня есть класс, который называется DateField
, который имеет строку Value
имущество. Если вы установите это свойство в строку, которая может быть проанализирована на допустимую дату, установщик свойства устанавливает Value
к правильно отформатированной дате, например:
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
if (value == _Value)
{
return;
}
object result;
if (TryParse(value, out result))
{
_Value = Format(result);
}
else
{
_Value = value;
}
OnPropertyChanged("Value");
}
}
Я создаю TextBox, который связан с этим полем:
<DataTemplate DataType="{x:Type m:DateField}">
<TextBox
IsTabStop="True"
Text="{Binding Value, Mode=TwoWay, ValidatesOnDataErrors=True}">
</TextBox>
</DataTemplate>
Когда я вхожу, скажем, "010109"
в это поле и вкладку из него, Binding
соответственно устанавливает Value
свойство этой строки. Установщик свойств работает, _Value
правильно установлен на "01/01/2009"
(TryParse
реализация в этом классе немного более католическая в том, что он принимает, чем DateTime.TryParse
есть), а PropertyChanged
событие поднимается. Я знаю, что последний бит происходит, потому что другой объект, который подписан на список, обновляется.
Но TextBox
не делает. Почему бы и нет? Я поставил Value
Я поднял PropertyChanged
; что еще мне нужно делать?
2 ответа
Я думаю, что вы должны использовать конвертер и реализовать оба Convert
и ConvertBack
методы
Я думаю, что у меня это работает должным образом, но я не совсем доволен тем, как я это сделал.
Типичный шаблон для использования ValueConverter
это то, что ConvertBack
должен вернуть преобразованное значение, если разбор завершился успешно, и DependencyProperty.UnsetValue
если это не удалось. Я не могу этого сделать. Если я сделаю это, то Value
свойство не устанавливается. Таким образом, значение не проверяется, и никакая ошибка проверки не отображается в пользовательском интерфейсе.
То, что я сделал вместо этого, реализовано DateValueConverter
класс чей ConvertBack
метод возвращает либо проанализированный DateTime
или строка, которую он безуспешно пытался преобразовать. Value
собственность в моем DateTimeField
класс (на самом деле, в Field
класс, из которого он получен) выглядит так:
public object Value
{
get
{
return _Value;
}
set
{
if (value == _Value)
{
return;
}
if (!Validate(value))
{
return;
}
_Value = value;
OnPropertyChanged("Value");
}
}
Validate
Метод в основном просто смотрит на тип передаваемого значения: если это DateTime
тогда это действительно; если это строка, это не так.
Я не доволен этим, потому что это похоже на ValueConverter
не должен преобразовывать значение в два разных типа. Это похоже на взломать. Но, может быть, все в порядке. Мне нужно подумать об этом еще немного.