views:

108

answers:

1

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
+4  A: 

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.

Tobias Langner
excellent, yes, worked, thanks
Edward Tanguay
This is recommended in general when you have properties that trigger a PropertyChanged event, as you should only fire the event when the property actually changes.
Cameron MacFarland
This is very naive approach for the problem (in general). You cannot assume there is no conversion in between meaning, the value can (especially when dealing with real numbers) **always** be different than before. Although, when it works, well, it works :-)
macias