Как я могу избежать рекурсии при обновлении моих свойств ViewModel? - PullRequest
1 голос
/ 18 июня 2009

В моем представлении у меня есть ползунок и поле со списком .

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

Когда я изменяю поле со списком , я хочу, чтобы ползунок изменился.

Я могу обновить одно или другое, но если я пытаюсь обновить оба, я получаю StackOverflow error , поскольку одно свойство продолжает обновлять другое в бесконечном цикле.

Я пытался вставить Recalculate () , где обновление выполняется в одном месте, но все еще сталкиваюсь с проблемой рекурсии.

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

в представлении:

<ComboBox 
    ItemsSource="{Binding Customers}"
    ItemTemplate="{StaticResource CustomerComboBoxTemplate}"
    Margin="20"
    HorizontalAlignment="Left"
    SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"/>


<Slider Minimum="0" 
        Maximum="{Binding HighestCustomerIndex, Mode=TwoWay}" 
        Value="{Binding SelectedCustomerIndex, Mode=TwoWay}"/>

в ViewModel:

#region ViewModelProperty: SelectedCustomer
private Customer _selectedCustomer;
public Customer SelectedCustomer
{
    get
    {
        return _selectedCustomer;
    }

    set
    {
        _selectedCustomer = value;
        OnPropertyChanged("SelectedCustomer");
        SelectedCustomerIndex = _customers.IndexOf(_selectedCustomer);
    }
}
#endregion

#region ViewModelProperty: SelectedCustomerIndex
private int _selectedCustomerIndex;
public int SelectedCustomerIndex
{
    get
    {
        return _selectedCustomerIndex;
    }

    set
    {
        _selectedCustomerIndex = value;
        OnPropertyChanged("SelectedCustomerIndex");
        SelectedCustomer = _customers[_selectedCustomerIndex];
    }
}
#endregion

Ответы [ 2 ]

7 голосов
/ 18 июня 2009

попробуйте в наборе функций что-то вроде:

public int SelectedCustomerIndex
{
    get
    {
        return _selectedCustomerIndex;
    }

    set
    {
        if (value != _selectedCustomerIndex)
        {
         _selectedCustomerIndex = value;
         OnPropertyChanged("SelectedCustomerIndex");
         SelectedCustomer = _customers[_selectedCustomerIndex];
        }
    }
}

запускать события только при фактическом изменении значения. Таким образом, второй вызов свойства set с тем же значением не вызывает другого события изменения.

Конечно, вы должны сделать это и для другой собственности.

0 голосов
/ 31 июля 2016

Оба свойства вызываются друг от друга, следовательно, рекурсия. Не имеет отношения к связыванию вообще. Правильный способ состоит в том, чтобы изменять друг друга и запускать уведомление об изменении обоих свойств при изменении любого свойства:

    public Customer SelectedCustomer
    {
        get
        {
            return _selectedCustomerIndex;
        }

        set
        {
            _selectedCustomer = value;
            _selectedCustomerIndex = _customers.IndexOf(value);

            OnPropertyChanged("SelectedCustomer");
            OnPropertyChanged("SelectedCustomerIndex");
        }
    }

    public int SelectedCustomerIndex
    {
        get
        {
            return _selectedCustomerIndex;
        }

        set
        {
            _selectedCustomerIndex = value;
            _selectedCustomer = _customers[_selectedCustomerIndex];

            OnPropertyChanged("SelectedCustomer");
            OnPropertyChanged("SelectedCustomerIndex");
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...