Значение TextFox WPF не изменяется на OnPropertyChanged - PullRequest
6 голосов
/ 16 июня 2010

У меня есть 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 достигнут (я это перезаписал), представление не изменяется. Как я могу сделать эту работу?

Спасибо, Хосе Таварес

Ответы [ 3 ]

5 голосов
/ 17 июня 2010

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

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");
        }
    }
}

Обновление:

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

<TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding RunAfter, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TestStepTextBox}"/>
3 голосов
/ 16 июня 2010

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

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

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

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

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

1 голос
/ 04 апреля 2011

У меня была такая же ситуация.Я написал следующее, и это сработало.

<TextBox Grid.Column="3" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" Text="{Binding Path=FirstName}"></TextBox>

И

public string FirstName
    {
        get { return _client.FirstName; }
        set
        {
            if (value == _client.FirstName)
                return;
            else
                _client.FirstName = value;
            OnPropertyChanged("FirstName");
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...