9

I bound a ListBox to a Queue<string>. When I enqueue/dequeue items, the ListBox does not update.

I have helpers for enqueue/dequeue to raise property change

protected void EnqueueWork(string param)
{
    Queue.Enqueue(param);
    RaisePropertyChanged("Queue");
}

protected string DequeueWork()
{
    string tmp = Queue.Dequeue();
    RaisePropertyChanged("Queue");
    return tmp;
} 
Jiew Meng
  • 84,767
  • 185
  • 495
  • 805
  • How do you bind a listbox to a queue? I get an error saying it needs to bind to an IList or IListSource – vkapadia Jun 30 '17 at 18:46

2 Answers2

28

Have you implemented INotifyCollectionChanged ? you need this for notifications of actions like adding or removing items from a collection.

here is a simple implementation for queue:

public class ObservableQueue<T> : INotifyCollectionChanged, IEnumerable<T>
{
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    private readonly Queue<T> queue = new Queue<T>();

    public void Enqueue(T item)
    {
        queue.Enqueue(item);
        if (CollectionChanged != null)
            CollectionChanged(this, 
                new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Add, item));
    }

    public T Dequeue()
    {
        var item = queue.Dequeue();
        if (CollectionChanged != null)
            CollectionChanged(this, 
                new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Remove, item));
        return item;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return queue.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Dean Chalk
  • 20,076
  • 6
  • 59
  • 90
  • Do you mean the same as @ArsenMkrt where I should create a `ObservableQueue` that extends `INotifyPropertyChanged` or use ObservableCollection instead? I will like to create ObservableQueue as its more sementically correct. But how will I go about doing that? extend Queue and overwrite Enqueue/Dequeue? But what will I write to and what property do I need to raise property changed? – Jiew Meng Nov 24 '10 at 13:07
  • you need to implement INotifyCollectionChanged - see my edit for a simple implementation – Dean Chalk Nov 24 '10 at 13:17
  • I'm pretty new to this, so correct me if I'm wrong, but would this be a better way to implement this? https://pastebin.com/GggziXf6 – vkapadia Jun 30 '17 at 18:35
  • 2
    For future readers, I had to change the two `CollectionChanged` lines to the following to avoid the exception: For adding new item: `CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, queue.Count));`. For removing item: `CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, 0));`. i.e. you have to specify the item index at which the action is occurring. – dotNET Oct 12 '17 at 17:28
1

You should use ObservableCollection not queue to do what you want, to allow ListBox to update on items adding and removing your class should implement INotifyCollectionChanged, ObservableCollection implements that interface, Or you can write your custom queue (ObservableQueue) that implements INotifyCollectionChanged interface

This post can help

Community
  • 1
  • 1
Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
  • Is raising property change from my Window (the data context) not enough? I could do the same with int, which I think is not observerble? The reason why I wanted to use queue is because of the usage, I just need to enqueue and dequeue stuff, but its ok, I can use a `ObservableCollection` still – Jiew Meng Nov 24 '10 at 12:23
  • Oh and btw, how will I extend the Queue class to make it observable? I tried extending the `Queue` then when I wanted to overwrite Enqueue, I don't know what to write – Jiew Meng Nov 24 '10 at 12:35
  • No @jiewmeng it is not enough, because your queue reference is not changed, but the content of the queue is changed... and WPF doesn't update reference because it is not changed – Arsen Mkrtchyan Nov 24 '10 at 13:19
  • see the reference I leave for how to make queue changeable... to be honest I never did it, you can just use observablecollection, to not create queue – Arsen Mkrtchyan Nov 24 '10 at 13:22