Значение WPF TextBox не изменяется на OnPropertyChanged

У меня есть TextBox, Значение которого связывается со свойством ViewModel:

        <TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding Mode=TwoWay, Path=RunAfter}" Style="{StaticResource TestStepTextBox}"/>

Набор и добирается, хорошо работали, пока я не пытался добавить некоторую проверку, когда Значение установлено:

    private int _runAfter = 0;
    public string RunAfter
    {
        get
        {
            return _runAfter.ToString();
        }

        set
        {
            int val = int.Parse(value);

            if (_runAfter != val)
            {
                if (val < _order)
                    _runAfter = val;
                else
                {
                    _runAfter = 0;
                    OnPropertyChanged("RunAfter");
                }
            }
        }
    }

Хотя OnPropertyChanged достигнут (у меня есть dubugged, что), Представление не изменяется. Как я могу сделать эту работу?

Спасибо, José Tavares

6
задан jpsstavares 16 June 2010 в 17:47
поделиться

2 ответа

Проблема в том, что вы обновляете источник для Binding, в то время как Binding обновляет ваше свойство. WPF фактически не проверяет значение вашего свойства, когда поднимает событие PropertyChanged в ответ на обновление Binding. Вы можете решить эту проблему, используя Диспетчер для задержки распространения события в этой ветке:

set
{
    int val = int.Parse(value);

    if (_runAfter != val)
    {
        if (val < _order)
        {
            _runAfter = val;
            OnPropertyChanged("RunAfter");
        }
        else
        {
            _runAfter = 0;
            Dispatcher.CurrentDispatcher.BeginInvoke(
                new Action<String>(OnPropertyChanged), 
                DispatcherPriority.DataBind, "RunAfter");
        }
    }
}

Update:

Другая вещь, которую я заметил, это то, что Binding на вашем TextBox использует стандартный UpdateSourceTrigger, который происходит, когда TextBox теряет фокус. В этом режиме вы не увидите, как текст изменится на 0, пока TextBox не потеряет фокус. Если вы измените его на PropertyChanged, вы увидите, что это произойдет немедленно. В противном случае, ваше свойство не будет установлено, пока ваш TextBox не потеряет фокус:

<TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding RunAfter, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TestStepTextBox}"/>
5
ответ дан 10 December 2019 в 02:42
поделиться

Несколько вещей, которые я заметил здесь.

Если у вас нет веских причин для предоставления свойства RunAfter в виде строки, нет причин, по которым оно не может быть int. Это сэкономит вам приведения в сеттере (а также скрывающегося возможного исключение InvalidCastException, если пользователь введет в поле что-то не целое число).

Во-вторых, вызов OnPropertyChanged() должен происходить вне внутренней инструкции if, как по следующему:

if(_runAfter != val)
{
    if(val < _order)
        _runAfter = val;
    else
        _runAfter = 0;
    OnPropertyChanged("RunAfter");
}

Поскольку _runAfter local обновляется в обоих путях условного условия, OnPropertyChanged() должен вызываться независимо от принятой ветви. Я надеюсь, что это поможет вам указать правильное направление!

3
ответ дан 10 December 2019 в 02:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: