Enum Properties not updating across CollectionViews

405 views Asked by At

I have a class, "MainViewModel" that includes an Observable Collection of ColourMappingViewModel, and references out to two other ViewModels, one which is used to update the ColourMappingViewModels (ColourControllerViewModel), and one which contains a CollectionView which is used to display a particular subset of these ColourMappingViewModels (ColourSelectionViewModel). Both these classes are passed the ObservableCollection to bind to.

ColourMappingViewModel has two properties: The Color , and the Type.

public class ColourMappingViewModel : ViewModel,
{
    public Color TextColour
    {
        get
        {
            return (Color)ColorConverter.ConvertFromString(_colourMapping.TextColour);
        }
        set
        {
            _colourMapping.TextColour = value.ToString().Remove(1, 2);
            OnPropertyChanged();
        }
    }


    public ColourMappingUsageType Type
    {
        get
        {
            return _colourMapping.Usage;
        }
        set
        {                
            _colourMapping.Usage = value;
            OnPropertyChanged()
        }
    }

}

ColourController includes a DataGrid, with the Type column including a ComboBox which binds to a collection of the enum types and the "Type" property like so:

  ItemsSource="{Binding Types, Mode=OneWay}"
  SelectedValue="{Binding Type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 

And similarly, another ComboBox containing the ColourList, bound like so:

ItemsSource="{Binding DataContext.ColoursList,
             RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type view:ColourController}}}"
             SelectedItem="{Binding BackgroundColour, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

The CollectionView on ColourSelectionViewModel filters the list based on the value of "Type", and I have another ComboBox on my ColourSelection view that is bound to this CollectionView.

Now. If I update the "TextColour" of in the ColourController, this is reflected in the ColourSelector - I can see the changes.

If I update the 'Type', though, the whole thing falls over with a StackOverflowException due to "OnPropertyChanged()" being repeatedly called. My question is, why!?

1

There are 1 answers

4
Andrei Tătar On BEST ANSWER

Update your code to:

public Color TextColour
{
    get
    {
        //it would be faster to convert in the set, not in the get
        //get is called more often
        return (Color)ColorConverter.ConvertFromString(_colourMapping.TextColour);
    }
    set
    {
        var converted = value.ToString().Remove(1, 2);
        if (_colourMapping.TextColour == converted) return;
        _colourMapping.TextColour = converted;
        OnPropertyChanged();
    }
}


public ColourMappingUsageType Type
{
    get
    {
        return _colourMapping.Usage;
    }
    set
    {                
        if (_colourMapping.Usage == value) return;
        _colourMapping.Usage = value;
        OnPropertyChanged()
    }
}