1

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);

            }
4

3 に答える 3

1

キューの代わりに監視可能なコレクションを使用します。これにより、コレクションが更新されたときにビューに自動的に通知されます(追加/削除など)。

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;
    }
}
于 2013-01-25T12:20:11.240 に答える
0
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.

于 2013-01-25T12:02:29.273 に答える
0

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);
        }
    }
}
于 2013-01-25T12:12:30.940 に答える