Двухстороннее связывание 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 не должен преобразовывать значение в два разных типа. Это похоже на взломать. Но, может быть, все в порядке. Мне нужно подумать об этом еще немного.

Другие вопросы по тегам