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

Я только что заметил, что текстовые поля WPF, привязанные к числовым данным, не срабатывают Property Set, когда происходят нечисловые события, такие как ввод букв/пробелов или очистка текста. Это становится проблемой, когда я пытаюсь проверить, что текстовое поле имеет допустимый номер. Если пользователь вводит 5 и нажимает клавишу Backspace, свойство с привязкой к данным остается равным 5, а текстовое поле выглядит пустым! У меня нет возможности отключить кнопку, чтобы остановить дальнейший прогресс. Можно ли как-то включить нечисловые уведомления при привязке к числовым данным? Или я вынужден использовать конвертер строковых свойств/данных? Спасибо.


person Pakman    schedule 25.04.2011    source источник


Ответы (1)


Если вам не нравится преобразователь по умолчанию, вам нужно создать свой собственный, который возвращает допустимое значение, если ввод пуст или не поддается анализу.

public class IntBindingConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string input = value as string;
        if (String.IsNullOrWhiteSpace(input))
        {
            return 0;
        }
        else
        {
            int outInt;
            if (int.TryParse(input, out outInt))
            {
                return outInt;
            }
            else
            {
                return 0;
            }
        }
    }
}

Пример использования:

<TextBox>
    <TextBox.Text>
        <Binding Path="Max">
            <Binding.Converter>
                <vc:IntBindingConverter/>
            </Binding.Converter>
        </Binding>
    </TextBox.Text>
</TextBox>

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

person H.B.    schedule 25.04.2011
comment
Я решил создать подкласс TextBox и переопределить OnTextChanged(), поэтому, когда this.Text был нулевым/пустым, я бы установил для него значение 0. Поскольку вы, вероятно, правы насчет конвертера по умолчанию, и ваш код определенно решит мою проблему, я приму ваш отвечать. Спасибо. - person Pakman; 27.04.2011
comment
Создание подкласса TextBox для этого звучит как излишество для меня, но для каждого свое... - person H.B.; 27.04.2011
comment
Ха-ха, не только это - это также позволило мне предотвратить набор букв - person Pakman; 28.04.2011
comment
Это более разумно, я бы, вероятно, использовал для этого проверку ввода через ValidationRules. - person H.B.; 28.04.2011
comment
Я реализую IDataErrorInfo в своей модели представления, где я включаю имя столбца и вызываю ViewModelBase.Validate(() => _model.Property). К каждому свойству применяется ValidationAttribute, который указывает, как Validate должен проверять его. Этот метод позволяет избежать загромождения моего XAML и предоставляет моей модели возможность сказать, что она действительна. Как ValidationRules сообщит VM/M, когда все свойства действительны? - person Pakman; 28.04.2011
comment
ValidationRules гарантирует, что недействительные данные никогда не будут переданы обратно в объект данных. Но поскольку вы не можете остановить пользователя, они здесь также неприменимы. - person H.B.; 28.04.2011