Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can use something like this to keep your ObservableCollections synchronised between the model and view model:</p> <pre><code>/// &lt;summary&gt; /// Keeps one collection synchronised with another. /// &lt;/summary&gt; /// &lt;typeparam name="Source"&gt;The type of the source items.&lt;/typeparam&gt; /// &lt;typeparam name="Destination"&gt;The type of the destination items.&lt;/typeparam&gt; public class CollectionSync&lt;Source, Destination&gt; { private readonly Func&lt;Source, Destination&gt; _destItemFactory; private readonly Action&lt;Destination&gt; _destItemRemover; private readonly IList&lt;Destination&gt; _destList; private readonly IList&lt;Source&gt; _sourceList; /// &lt;summary&gt; /// Initializes a new instance of the &lt;see cref="CollectionSync&amp;lt;Source, Destination&amp;gt;"/&gt; class. /// &lt;/summary&gt; /// &lt;param name="sourceList"&gt;The source list.&lt;/param&gt; /// &lt;param name="destList"&gt;The destination list.&lt;/param&gt; /// &lt;param name="destItemFactory"&gt;Factory method which creates a Destination for a given Source.&lt;/param&gt; /// &lt;param name="destItemRemover"&gt;Method called when a Destination is removed.&lt;/param&gt; public CollectionSync(IList&lt;Source&gt; sourceList, IList&lt;Destination&gt; destList, Func&lt;Source, Destination&gt; destItemFactory, Action&lt;Destination&gt; destItemRemover) { _destItemFactory = destItemFactory; _destItemRemover = destItemRemover; _sourceList = sourceList; _destList = destList; ((INotifyCollectionChanged) _sourceList).CollectionChanged += SourceCollection_CollectionChanged; PopulateWithAllItems(); } private void PopulateWithAllItems() { foreach (Source sourceItem in _sourceList) _destList.Add(_destItemFactory(sourceItem)); } private void SourceCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { switch (args.Action) { case NotifyCollectionChangedAction.Add: OnItemsAdded(args.NewStartingIndex, args.NewItems); break; case NotifyCollectionChangedAction.Remove: OnItemsRemoved(args.OldStartingIndex, args.OldItems); break; case NotifyCollectionChangedAction.Reset: OnItemsReset(); break; case NotifyCollectionChangedAction.Move: case NotifyCollectionChangedAction.Replace: throw new NotImplementedException(); } } private void OnItemsReset() { _destList.Clear(); PopulateWithAllItems(); } private void OnItemsRemoved(int index, ICollection items) { int itemCount = items.Count; for (int i = 0; i &lt; itemCount; i++) { Destination removed = _destList[index]; _destList.RemoveAt(index); if (_destItemRemover != null) _destItemRemover(removed); } } private void OnItemsAdded(int index, IList items) { int itemIndex = index; foreach (Source item in items) { // Add to Items collection _destList.Insert(itemIndex, _destItemFactory(item)); itemIndex++; } } } </code></pre> <p>Taking your Order/OrderDetails example, in your Order view model you would hook up the two ObservableCollections like this:</p> <pre><code>_modelToViewModelSync = new CollectionSync&lt;IOrderDetail, OrderDetailViewModel&gt;( orderDetailModels, // the list of your order details models OrderDetails, // the list of order details view models exposed by the Order view model x =&gt; new OrderDetailViewModel(x), // factory method to create a view model null); // do something here if you care when your view models are removed </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload