Question

In my View I have a slider and a combobox.

When I change the slider, I want the combobox to change.

When I change the combobox, I want the slider to change.

I can udpate one or the other, but if I try to update both I get a StackOverflow error since one property keeps updating the other in an infinite loop.

I've tried putting in a Recalculate() where the updating is done in one place, but still run into the recursion problem.

How can I have each control update the other without going into recursion?

in View:

<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}"/>

in 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
Was it helpful?

Solution

try in the set functions something like:

public int SelectedCustomerIndex
{
    get
    {
        return _selectedCustomerIndex;
    }

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

to fire the events only when there is an actual change in value. This way, a second call to the set property with the same value does not cause another change event.

You have to do that for the other property as well of course.

OTHER TIPS

Both properties are called from each other, hence the recursion. Not related to binding at all. Proper way is to change each other and fire change notification for both properties when either property changes:

    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");
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top