Reputation: 21260
I have a model collection that is referenced from a most parts of my code.
public class TraceEntryQueue
{
private readonly Queue<TraceEntry> _logEntries;
public TraceEntryQueue()
{
_logEntries = new Queue<TraceEntry>();
}
public void AddEntry(TraceEntry newEntry)
{
_logEntries.Enqueue(newEntry);
}
public List<TraceEntry> GetAsList()
{
return _logEntries.ToList();
}
}
This collection is presented in one of my views.
public class LoggingViewModel : ViewModelBase
{
private ICollectionView _customers;
public ICollectionView Customers
{
get
{
return _customers;
}
private set
{
_customers = value;
}
}
public LoggingViewModel(TraceEntryQueue traceQueue)
{
Customers = CollectionViewSource.GetDefaultView(traceQueue.GetAsList());
Customers.SortDescriptions.Add(new SortDescription("Index", ListSortDirection.Descending));
Customers.Refresh();
}
}
The question is how I can notify my view to reload the collection when I add new entries via
public void AddEntry(TraceEntry newEntry)
{
_logEntries.Enqueue(newEntry);
}
Upvotes: 1
Views: 936
Reputation: 885
Use an observable collection instead of a queue. This will automatically notify your view when the collection is updated (add/remove etc.)
public class TraceEntryQueue
{
private readonly ObservableCollection<TraceEntry> _logEntries;
public TraceEntryQueue()
{
_logEntries = new ObservableCollection<TraceEntry>();
}
public void AddEntry(TraceEntry newEntry)
{
_logEntries.Add(newEntry);
}
public ObservableCollection<TraceEntry> GetLogEntries()
{
return _logEntries;
}
}
Upvotes: 1
Reputation: 3791
As @RobJohnson mentionned, you can use an ObservableCollection. However, if you need to create your own collection class, you should implement the INotifyCollectionChanged interface:
public class TraceEntryQueue : INotifyCollectionChanged
{
private readonly Queue<TraceEntry> _logEntries;
public TraceEntryQueue()
{
_logEntries = new Queue<TraceEntry>();
}
public void AddEntry(TraceEntry newEntry)
{
_logEntries.Enqueue(newEntry);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newEntry));
}
public List<TraceEntry> GetAsList()
{
return _logEntries.ToList();
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(this, e);
}
}
}
Upvotes: 0
Reputation: 19885
public class TraceEntryQueue
{
private readonly Queue<TraceEntry> _logEntries;
private readonly ICollectionView _logEntriesView;
public TraceEntryQueue()
{
_logEntries = new Queue<TraceEntry>();
_logEntriesView = CollectionViewSource.GetDefaultView(logEntries.ToList());
}
//....
public void AddEntry(TraceEntry newEntry)
{
_logEntries.Enqueue(newEntry);
_logEntriesView.SourceCollection = logEntries.ToList();
_logEntriesView.Refresh();
}
public ICollectionView GetAsView()
{
return _logEntriesView;
}
}
Use GetAsView
and bind directly to your datagrid / listbox / listview.
Upvotes: 0