/// <summary> /// Updates contents of the ItemsSource when FeatureDataGrid's associated graphic collection changes. /// </summary> /// <param name="sender">Observable collection of Graphic.</param> /// <param name="e">Collection changed event arguments.</param> private void UpdateItemsSource(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { IList newItems = e.NewItems; IList oldItems = e.OldItems; if (ItemsSource == null) { SetItemsSource(sender as ObservableCollection <Graphic>); } else { if ((ItemsSource as PagedCollectionView) != null) { object currentItem = (ItemsSource as PagedCollectionView).CurrentItem; if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset) { var features = (from object a in ItemsSource select DataSourceCreator.GetGraphicSibling(a)); newItems = (sender as ObservableCollection <Graphic>).Except(features).ToList(); oldItems = features.Except(sender as ObservableCollection <Graphic>).ToList(); } if (newItems != null && newItems.Count > 0) // New item(s) added { bool shouldResetItemsSource = false; IEnumerator enumItemsSource = ItemsSource.GetEnumerator(); if (enumItemsSource != null) { if (enumItemsSource.MoveNext()) { if (!AllAttributesMatch(enumItemsSource.Current.GetType().GetProperties(), (newItems[0] as Graphic).Attributes)) { shouldResetItemsSource = true; } } else { shouldResetItemsSource = true; } } if (shouldResetItemsSource) { UnregisterGraphicCollectionEventHandlers(); SetItemsSource(sender as ObservableCollection <Graphic>); IEnumerator enumAddedGraphics = newItems.GetEnumerator(); while (enumAddedGraphics.MoveNext()) { Graphic graphic = enumAddedGraphics.Current as Graphic; if (graphic != null) { graphic.AttributeValueChanged += Graphic_AttributeValueChanged; } } } else { IEnumerator enumAddedGraphics = newItems.GetEnumerator(); List <Graphic> selected = GraphicsLayer.SelectedGraphics.ToList(); while (enumAddedGraphics.MoveNext()) { Graphic graphic = enumAddedGraphics.Current as Graphic; if (graphic != null) { if (graphic.Selected) { selected.Add(graphic); } ItemsSource.AddToDataSource(featureLayerInfo, graphic, objectType); graphic.AttributeValueChanged += Graphic_AttributeValueChanged; } } RestorePreviousSelection(selected); } } if (oldItems != null && oldItems.Count > 0) // Item(s) removed { int selCount = SelectedItems.Count; // In Silverlight removing a graphic from the GraphicsCollection causes to lose current // selection in both GraphicsLayer and the FeatureDataGrid. // Preserving selected items in the FeatureDataGrid: List <Graphic> selItems = new List <Graphic>(selCount); for (int i = 0; i < selCount; i++) { var row = SelectedItems[i]; var graphic = DataSourceCreator.GetGraphicSibling(row); selItems.Add(graphic); } IEnumerator enumRemovedGraphics = oldItems.GetEnumerator(); while (enumRemovedGraphics.MoveNext()) { Graphic graphic = enumRemovedGraphics.Current as Graphic; int idxInItemsSource = GetRowIndexInItemsSource(graphic); if (graphic != null && idxInItemsSource > -1) { if (graphic != null) { selItems.Remove(graphic); } ItemsSource.RemoveFromDataSource(idxInItemsSource, objectType); // RemoveFromDataSource() method causes first item in the ItemsSource to be selected when there were no // items selected in the data grid. We should avoid this selection by removing it from the selection: if (selCount == 0 && SelectedItems.Count == 1) { SelectedItems.Clear(); } graphic.AttributeValueChanged -= Graphic_AttributeValueChanged; SelectedGraphics.Remove(graphic); } } RestorePreviousSelection(selItems); } } else { // If exiting ItemsSource is not a PagedCollectionView then it was empty before // just populate it with everything in GraphicsLayer. SetItemsSource((GraphicsLayer != null && GraphicsLayer.Graphics != null) ? (IList <Graphic>)GraphicsLayer.Graphics : new List <Graphic>()); } } ShowNumberOfRecords(); }