internal SelectedCellsChangedEventArgs(DataGrid owner, VirtualizedCellInfoCollection addedCells, VirtualizedCellInfoCollection removedCells) { _addedCells = (addedCells != null) ? addedCells : VirtualizedCellInfoCollection.MakeEmptyCollection(owner); _removedCells = (removedCells != null) ? removedCells : VirtualizedCellInfoCollection.MakeEmptyCollection(owner); Debug.Assert(_addedCells.IsReadOnly, "_addedCells should have ended up as read-only."); Debug.Assert(_removedCells.IsReadOnly, "_removedCells should have ended up as read-only."); }
/// <summary> /// Notify the owning DataGrid of changes to this collection. /// </summary> protected override void OnCollectionChanged(NotifyCollectionChangedAction action, VirtualizedCellInfoCollection oldItems, VirtualizedCellInfoCollection newItems) { Owner.OnSelectedCellsChanged(action, oldItems, newItems); }
/// <summary> /// Updates the IsSelected property on cells due to a change in SelectedCells. /// </summary> private void UpdateIsSelected(VirtualizedCellInfoCollection cells, bool isSelected) { if (cells != null) { int numCells = cells.Count; if (numCells > 0) { // Determine if it would be better to iterate through all the visible cells // instead of through the update list. bool useTracker = false; // For "small" updates it's simpler to just go through the cells, get the container, // and update IsSelected. For "large" updates, it's faster to go through the visible // cells, see if they're in the collection, and then update IsSelected. // Determining small vs. large is going to be done using a magic number. // 750 is close to the number of visible cells Excel shows by default on a 1280x1024 monitor. if (numCells > 750) { int numTracker = 0; int numColumns = _columns.Count; ContainerTracking<DataGridRow> rowTracker = _rowTrackingRoot; while (rowTracker != null) { numTracker += numColumns; if (numTracker >= numCells) { // There are more cells visible than being updated break; } rowTracker = rowTracker.Next; } useTracker = (numCells > numTracker); } if (useTracker) { ContainerTracking<DataGridRow> rowTracker = _rowTrackingRoot; while (rowTracker != null) { DataGridRow row = rowTracker.Container; DataGridCellsPresenter cellsPresenter = row.CellsPresenter; if (cellsPresenter != null) { ContainerTracking<DataGridCell> cellTracker = cellsPresenter.CellTrackingRoot; while (cellTracker != null) { DataGridCell cell = cellTracker.Container; DataGridCellInfo cellInfo = new DataGridCellInfo(cell); if (cells.Contains(cellInfo)) { cell.SyncIsSelected(isSelected); } cellTracker = cellTracker.Next; } } rowTracker = rowTracker.Next; } } else { foreach (DataGridCellInfo cellInfo in cells) { DataGridCell cell = TryFindCell(cellInfo); if (cell != null) { cell.SyncIsSelected(isSelected); } } } } } }
/// <summary> /// Direct notification from the SelectedCells collection of a change. /// </summary> internal void OnSelectedCellsChanged(NotifyCollectionChangedAction action, VirtualizedCellInfoCollection oldItems, VirtualizedCellInfoCollection newItems) { DataGridSelectionMode selectionMode = SelectionMode; DataGridSelectionUnit selectionUnit = SelectionUnit; if (!IsUpdatingSelectedCells && (selectionUnit == DataGridSelectionUnit.FullRow)) { throw new InvalidOperationException(SR.Get(SRID.DataGrid_CannotSelectCell)); } // Update the pending list of changes if (oldItems != null) { // When IsUpdatingSelectedCells is true, there may have been cells // added to _pendingSelectedCells that are now being removed. // These cells should be removed from _pendingSelectedCells and // not added to _pendingUnselectedCells. if (_pendingSelectedCells != null) { VirtualizedCellInfoCollection.Xor(_pendingSelectedCells, oldItems); } if (_pendingUnselectedCells == null) { _pendingUnselectedCells = oldItems; } else { _pendingUnselectedCells.Union(oldItems); } } if (newItems != null) { // When IsUpdatingSelectedCells is true, there may have been cells // added to _pendingUnselectedCells that are now being removed. // These cells should be removed from _pendingUnselectedCells and // not added to _pendingSelectedCells. if (_pendingUnselectedCells != null) { VirtualizedCellInfoCollection.Xor(_pendingUnselectedCells, newItems); } if (_pendingSelectedCells == null) { _pendingSelectedCells = newItems; } else { _pendingSelectedCells.Union(newItems); } } // Not deferring change notifications if (!IsUpdatingSelectedCells) { // This is most likely the case when SelectedCells was updated by // the application. In this case, some fix-up is required, and // the public event needs to fire. // This will fire the event on dispose using (UpdateSelectedCells()) { if ((selectionMode == DataGridSelectionMode.Single) && // Single select mode (action == NotifyCollectionChangedAction.Add) && // An item was added (_selectedCells.Count > 1)) // There is more than one selected cell { // When in single selection mode and there is more than one selected // cell, remove all cells but the new cell. _selectedCells.RemoveAllButOne(newItems[0]); } else if ((action == NotifyCollectionChangedAction.Remove) && (oldItems != null) && (selectionUnit == DataGridSelectionUnit.CellOrRowHeader)) { // If removed cells belong to rows that are selected, then the row // needs to be unselected (other selected cells may remain selected). bool alreadyUpdating = IsUpdatingSelectedItems; if (!alreadyUpdating) { BeginUpdateSelectedItems(); } try { object lastRowItem = null; foreach (DataGridCellInfo cellInfo in oldItems) { // First ensure that we haven't already checked the item object rowItem = cellInfo.Item; if (rowItem != lastRowItem) { lastRowItem = rowItem; if (SelectedItems.Contains(rowItem)) { // Remove the item SelectedItems.Remove(rowItem); } } } } finally { if (!alreadyUpdating) { EndUpdateSelectedItems(); } } } } } }
/// <summary> /// Fires the public change event when there are pending cell changes. /// </summary> private void NotifySelectedCellsChanged() { if (((_pendingSelectedCells != null) && (_pendingSelectedCells.Count > 0)) || ((_pendingUnselectedCells != null) && (_pendingUnselectedCells.Count > 0))) { // Create the new event args SelectedCellsChangedEventArgs e = new SelectedCellsChangedEventArgs(this, _pendingSelectedCells, _pendingUnselectedCells); // Calculate the previous and current selection counts to determine if commands need invalidating int currentSelectionCount = _selectedCells.Count; int unselectedCellCount = (_pendingUnselectedCells != null) ? _pendingUnselectedCells.Count : 0; int selectedCellCount = (_pendingSelectedCells != null) ? _pendingSelectedCells.Count : 0; int previousSelectionCount = currentSelectionCount - selectedCellCount + unselectedCellCount; // Clear the pending lists _pendingSelectedCells = null; _pendingUnselectedCells = null; // Fire the public event OnSelectedCellsChanged(e); // If old or new selection is empty - invalidate Copy command if ((previousSelectionCount == 0) || (currentSelectionCount == 0)) { // The Copy command needs to have CanExecute run CommandManager.InvalidateRequerySuggested(); } } }
// Token: 0x060055BB RID: 21947 RVA: 0x0017C181 File Offset: 0x0017A381 internal SelectedCellsChangedEventArgs(DataGrid owner, VirtualizedCellInfoCollection addedCells, VirtualizedCellInfoCollection removedCells) { this._addedCells = ((addedCells != null) ? addedCells : VirtualizedCellInfoCollection.MakeEmptyCollection(owner)); this._removedCells = ((removedCells != null) ? removedCells : VirtualizedCellInfoCollection.MakeEmptyCollection(owner)); }