1
votes

A ObservableCollection

private ObservableCollection<string> _items = new ObservableCollection<string>();

public ObservableCollection<string> Items { get { return _items; } }

is updated on user interactions (a TextBox event).

In a ListBox I'll show the current values

Binding listBinding = new Binding {Source = Items};
listbox.SetBinding(ListBox.ItemsSourceProperty, listBinding);

That works so far: When adding a new value the list is immediately updated.

But now I have to requirements:

  • Sort values
  • Add one item at the beginning of the list

I solved as followed:

public IEnumerable<string> ItemsExtended
{
  get
  {
    return new[] { "first value" }.Concat(Items.OrderBy(x => x));
  }
}

I changed the binding to that IEnumerable and the list contains a sorted list with "first value" at position one.

Unfortunately when the list should be updated on user interaction it does not work any more. Even changing IEnumerable to ObservableCollection again and directly referring to the private ObservableCollection does not solve the issue:

return new ObservableCollection<string> (new[] { "bla" }.Concat(_items.OrderBy(x => x)));

How to update the list when _items changes?

1

1 Answers

1
votes

Off the top of my head. You could implement INotifyPropertyChanged for the class that your collection belongs to . After that add a CollectionChanged handler for your _items collection and fire PropertyChanged("ItemsExtended") in that handler. Also using yield return in the getter will avoid creating a new collection just to add the item at the top.

It should look something like this

public partial class MyClass : INotifyPropertyChanged
{

    ObservableCollection<string> _items;
    public MyClass()
    {
        _items = new ObservableCollection<string>();
        _items.CollectionChanged += (s, e) => { OnPropertyChanged("Items"); };
    }

    public IEnumerable<string> Items 
    { 
        get 
        {
            yield return "first value";
            foreach (var item in _items.OrderBy(x=>x))
                yield return item;

        } 
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}