protected override void RemoveItem(int columnIndex) { // if (this._owningGrid.InDisplayIndexAdjustments) { // We are within columns display indexes adjustments. We do not allow changing the column collection while adjusting display indexes. throw DataGridError.DataGrid.CannotChangeColumnCollectionWhileAdjustingDisplayIndexes(); } Debug.Assert(columnIndex >= 0 && columnIndex < this.ItemsInternal.Count); Debug.Assert(this._owningGrid != null); DataGridColumn dataGridColumn = this.ItemsInternal[columnIndex]; // DataGridCellCoordinates newCurrentCellCoordinates = this._owningGrid.OnRemovingColumn(dataGridColumn); InvalidateCachedColumnsOrder(); this.ItemsInternal.RemoveAt(columnIndex); if (dataGridColumn.Visibility == Visibility.Visible) { this.VisibleEdgedColumnsWidth -= dataGridColumn.ActualWidth; } dataGridColumn.OwningGrid = null; this._owningGrid.OnRemovedColumn_PreNotification(dataGridColumn); this._owningGrid.OnColumnCollectionChanged_PreNotification(false /*columnsGrew*/); base.RemoveItem(columnIndex); this._owningGrid.OnRemovedColumn_PostNotification(newCurrentCellCoordinates); this._owningGrid.OnColumnCollectionChanged_PostNotification(false /*columnsGrew*/); }
public override bool Equals(object o) { DataGridCellCoordinates dataGridCellCoordinates = o as DataGridCellCoordinates; if (dataGridCellCoordinates != null) { return(dataGridCellCoordinates.ColumnIndex == this.ColumnIndex && dataGridCellCoordinates.RowIndex == this.RowIndex); } return(false); }
protected override void InsertItem(int columnIndex, DataGridColumn dataGridColumn) { Debug.Assert(this._owningGrid != null); try { this._owningGrid.NoCurrentCellChangeCount++; if (this._owningGrid.InDisplayIndexAdjustments) { // We are within columns display indexes adjustments. We do not allow changing the column collection while adjusting display indexes. throw DataGridError.DataGrid.CannotChangeColumnCollectionWhileAdjustingDisplayIndexes(); } if (dataGridColumn == null) { throw new ArgumentNullException("dataGridColumn"); } int columnIndexWithFiller = columnIndex; if (dataGridColumn != this.RowGroupSpacerColumn && this.RowGroupSpacerColumn.IsRepresented) { columnIndexWithFiller++; } // get the new current cell coordinates DataGridCellCoordinates newCurrentCellCoordinates = this._owningGrid.OnInsertingColumn(columnIndex, dataGridColumn); // insert the column into our internal list this.ItemsInternal.Insert(columnIndexWithFiller, dataGridColumn); dataGridColumn.Index = columnIndexWithFiller; dataGridColumn.OwningGrid = this._owningGrid; dataGridColumn.RemoveEditingElement(); if (dataGridColumn.IsVisible) { this.VisibleEdgedColumnsWidth += dataGridColumn.ActualWidth; } // continue with the base insert this._owningGrid.OnInsertedColumn_PreNotification(dataGridColumn); this._owningGrid.OnColumnCollectionChanged_PreNotification(true /*columnsGrew*/); if (dataGridColumn != this.RowGroupSpacerColumn) { base.InsertItem(columnIndex, dataGridColumn); } this._owningGrid.OnInsertedColumn_PostNotification(newCurrentCellCoordinates, dataGridColumn.DisplayIndex); this._owningGrid.OnColumnCollectionChanged_PostNotification(true /*columnsGrew*/); } finally { this._owningGrid.NoCurrentCellChangeCount--; } }
private void RemoveItemPrivate(int columnIndex, bool isSpacer) { Debug.Assert(this._owningGrid != null); try { this._owningGrid.NoCurrentCellChangeCount++; if (this._owningGrid.InDisplayIndexAdjustments) { // We are within columns display indexes adjustments. We do not allow changing the column collection while adjusting display indexes. throw DataGridError.DataGrid.CannotChangeColumnCollectionWhileAdjustingDisplayIndexes(); } int columnIndexWithFiller = columnIndex; if (!isSpacer && this.RowGroupSpacerColumn.IsRepresented) { columnIndexWithFiller++; } Debug.Assert(columnIndexWithFiller >= 0 && columnIndexWithFiller < this.ItemsInternal.Count); DataGridColumn dataGridColumn = this.ItemsInternal[columnIndexWithFiller]; DataGridCellCoordinates newCurrentCellCoordinates = this._owningGrid.OnRemovingColumn(dataGridColumn); this.ItemsInternal.RemoveAt(columnIndexWithFiller); if (dataGridColumn.IsVisible) { this.VisibleEdgedColumnsWidth -= dataGridColumn.ActualWidth; } dataGridColumn.OwningGrid = null; dataGridColumn.RemoveEditingElement(); // continue with the base remove this._owningGrid.OnRemovedColumn_PreNotification(dataGridColumn); this._owningGrid.OnColumnCollectionChanged_PreNotification(false /*columnsGrew*/); if (!isSpacer) { base.RemoveItem(columnIndex); } this._owningGrid.OnRemovedColumn_PostNotification(newCurrentCellCoordinates); this._owningGrid.OnColumnCollectionChanged_PostNotification(false /*columnsGrew*/); } finally { this._owningGrid.NoCurrentCellChangeCount--; } }
internal DataGridCellCoordinates OnRemovingColumn(DataGridColumn dataGridColumn) { Debug.Assert(dataGridColumn != null); Debug.Assert(dataGridColumn.Index >= 0 && dataGridColumn.Index < this.ColumnsItemsInternal.Count); DataGridCellCoordinates newCurrentCellCoordinates; this._temporarilyResetCurrentCell = false; int columnIndex = dataGridColumn.Index; // Reset the current cell's address if there is one. if (this.CurrentColumnIndex != -1) { int newCurrentColumnIndex = this.CurrentColumnIndex; if (columnIndex == newCurrentColumnIndex) { DataGridColumn dataGridColumnNext = this.ColumnsInternal.GetNextVisibleColumn(this.ColumnsItemsInternal[columnIndex]); if (dataGridColumnNext != null) { if (dataGridColumnNext.Index > columnIndex) { newCurrentColumnIndex = dataGridColumnNext.Index - 1; } else { newCurrentColumnIndex = dataGridColumnNext.Index; } } else { DataGridColumn dataGridColumnPrevious = this.ColumnsInternal.GetPreviousVisibleNonFillerColumn(this.ColumnsItemsInternal[columnIndex]); if (dataGridColumnPrevious != null) { if (dataGridColumnPrevious.Index > columnIndex) { newCurrentColumnIndex = dataGridColumnPrevious.Index - 1; } else { newCurrentColumnIndex = dataGridColumnPrevious.Index; } } else { newCurrentColumnIndex = -1; } } } else if (columnIndex < newCurrentColumnIndex) { newCurrentColumnIndex--; } newCurrentCellCoordinates = new DataGridCellCoordinates(newCurrentColumnIndex, (newCurrentColumnIndex == -1) ? -1 : this.CurrentSlot); if (columnIndex == this.CurrentColumnIndex) { // If the commit fails, force a cancel edit if (!this.CommitEdit(DataGridEditingUnit.Row, false /*exitEditingMode*/)) { this.CancelEdit(DataGridEditingUnit.Row, false /*raiseEvents*/); } bool success = this.SetCurrentCellCore(-1, -1); Debug.Assert(success); } else { // Underlying data of deleted column is gone. It cannot be accessed anymore. // Do not end editing mode so that CellValidation doesn't get raised, since that event needs the current formatted value. this._temporarilyResetCurrentCell = true; bool success = SetCurrentCellCore(-1, -1); Debug.Assert(success); } } else { newCurrentCellCoordinates = new DataGridCellCoordinates(-1, -1); } // If the last column is removed, delete all the rows first. if (this.ColumnsItemsInternal.Count == 1) { ClearRows(false); } // Is deleted column scrolled off screen? if (dataGridColumn.Visibility == Visibility.Visible && !dataGridColumn.IsFrozen && this.DisplayData.FirstDisplayedScrollingCol >= 0) { // Deleted column is part of scrolling columns. if (this.DisplayData.FirstDisplayedScrollingCol == dataGridColumn.Index) { // Deleted column is first scrolling column this._horizontalOffset -= this._negHorizontalOffset; this._negHorizontalOffset = 0; } else if (!this.ColumnsInternal.DisplayInOrder(this.DisplayData.FirstDisplayedScrollingCol, dataGridColumn.Index)) { // Deleted column is displayed before first scrolling column Debug.Assert(this._horizontalOffset >= GetEdgedColumnWidth(dataGridColumn)); this._horizontalOffset -= GetEdgedColumnWidth(dataGridColumn); } if (this._hScrollBar != null && this._hScrollBar.Visibility == Visibility.Visible) // { this._hScrollBar.Value = this._horizontalOffset; } } return newCurrentCellCoordinates; }
internal void OnRemovedColumn_PostNotification(DataGridCellCoordinates newCurrentCellCoordinates) { // Update current cell if needed if (newCurrentCellCoordinates.ColumnIndex != -1) { Debug.Assert(this.CurrentColumnIndex == -1); SetAndSelectCurrentCell(newCurrentCellCoordinates.ColumnIndex, newCurrentCellCoordinates.Slot, false /*forceCurrentCellSelection*/); } }
internal DataGridCellCoordinates OnInsertingColumn(int columnIndexInserted, DataGridColumn insertColumn) { DataGridCellCoordinates newCurrentCellCoordinates; Debug.Assert(insertColumn != null); if (insertColumn.OwningGrid != null && insertColumn != this.ColumnsInternal.RowGroupSpacerColumn) { throw DataGridError.DataGrid.ColumnCannotBeReassignedToDifferentDataGrid(); } // Reset current cell if there is one, no matter the relative position of the columns involved if (this.CurrentColumnIndex != -1) { this._temporarilyResetCurrentCell = true; newCurrentCellCoordinates = new DataGridCellCoordinates(columnIndexInserted <= this.CurrentColumnIndex ? this.CurrentColumnIndex + 1 : this.CurrentColumnIndex, this.CurrentSlot); ResetCurrentCellCore(); } else { newCurrentCellCoordinates = new DataGridCellCoordinates(-1, -1); } return newCurrentCellCoordinates; }
internal void OnInsertedColumn_PostNotification(DataGridCellCoordinates newCurrentCellCoordinates, int newDisplayIndex) { // Update current cell if needed if (newCurrentCellCoordinates.ColumnIndex != -1) { Debug.Assert(this.CurrentColumnIndex == -1); SetAndSelectCurrentCell(newCurrentCellCoordinates.ColumnIndex, newCurrentCellCoordinates.Slot, this.ColumnsInternal.VisibleColumnCount == 1 /*forceCurrentCellSelection*/); if (newDisplayIndex < this.FrozenColumnCountWithFiller) { CorrectColumnFrozenStates(); } } }
public DataGridCellCoordinates(DataGridCellCoordinates dataGridCellCoordinates) : this(dataGridCellCoordinates.ColumnIndex, dataGridCellCoordinates.Slot) { }
internal DataGridCellCoordinates OnInsertingColumn(int columnIndexInserted, DataGridColumn insertColumn) { DataGridCellCoordinates newCurrentCellCoordinates; Debug.Assert(insertColumn != null); if (insertColumn.OwningGrid != null) { throw DataGridError.DataGrid.ColumnCannotBeReassignedToDifferentDataGrid(); } // check for correctness of frozen state - throws exception if state is incorrect. CorrectColumnFrozenState(insertColumn, columnIndexInserted); // Reset current cell if there is one, no matter the relative position of the columns involved if (this.CurrentColumnIndex != -1) { newCurrentCellCoordinates = new DataGridCellCoordinates(columnIndexInserted <= this.CurrentColumnIndex ? this.CurrentColumnIndex + 1 : this.CurrentColumnIndex, this.CurrentRowIndex); ResetCurrentCellCore(); } else { newCurrentCellCoordinates = new DataGridCellCoordinates(-1, -1); } return newCurrentCellCoordinates; }
internal void OnInsertedColumn_PostNotification(DataGridCellCoordinates newCurrentCellCoordinates) { // Update current cell if needed if (newCurrentCellCoordinates.ColumnIndex != -1) { Debug.Assert(this.CurrentColumnIndex == -1); bool success = SetAndSelectCurrentCell(newCurrentCellCoordinates.ColumnIndex, newCurrentCellCoordinates.RowIndex, this.ColumnsInternal.VisibleColumnCount == 1 /*forceCurrentCellSelection*/); Debug.Assert(success); } }
private bool SetCurrentCellCore(int columnIndex, int slot, bool commitEdit, bool endRowEdit) { Debug.Assert(columnIndex < this.ColumnsItemsInternal.Count); Debug.Assert(slot < this.SlotCount); Debug.Assert(columnIndex == -1 || this.ColumnsItemsInternal[columnIndex].IsVisible); Debug.Assert(!(columnIndex > -1 && slot == -1)); if (columnIndex == this.CurrentColumnIndex && slot == this.CurrentSlot) { Debug.Assert(this.DataConnection != null); Debug.Assert(this._editingColumnIndex == -1 || this._editingColumnIndex == this.CurrentColumnIndex); Debug.Assert(this.EditingRow == null || this.EditingRow.Slot == this.CurrentSlot || this.DataConnection.CommittingEdit); return true; } UIElement oldDisplayedElement = null; DataGridCellCoordinates oldCurrentCell = new DataGridCellCoordinates(this.CurrentCellCoordinates); object newCurrentItem = null; if (!this.RowGroupHeadersTable.Contains(slot)) { int rowIndex = this.RowIndexFromSlot(slot); if (rowIndex >= 0 && rowIndex < this.DataConnection.Count) { newCurrentItem = this.DataConnection.GetDataItem(rowIndex); } } if (this.CurrentColumnIndex > -1) { Debug.Assert(this.CurrentColumnIndex < this.ColumnsItemsInternal.Count); Debug.Assert(this.CurrentSlot < this.SlotCount); if (!IsInnerCellOutOfBounds(oldCurrentCell.ColumnIndex, oldCurrentCell.Slot) && this.IsSlotVisible(oldCurrentCell.Slot)) { oldDisplayedElement = this.DisplayData.GetDisplayedElement(oldCurrentCell.Slot); } if (!this.RowGroupHeadersTable.Contains(oldCurrentCell.Slot) && !this._temporarilyResetCurrentCell) { bool keepFocus = this.ContainsFocus; if (commitEdit) { if (!EndCellEdit(DataGridEditAction.Commit, true /*exitEditingMode*/, keepFocus, true /*raiseEvents*/)) { return false; } // Resetting the current cell: setting it to (-1, -1) is not considered setting it out of bounds if ((columnIndex != -1 && slot != -1 && IsInnerCellOutOfSelectionBounds(columnIndex, slot)) || IsInnerCellOutOfSelectionBounds(oldCurrentCell.ColumnIndex, oldCurrentCell.Slot)) { return false; } if (endRowEdit && !EndRowEdit(DataGridEditAction.Commit, true /*exitEditingMode*/, true /*raiseEvents*/)) { return false; } } else { this.CancelEdit(DataGridEditingUnit.Row, false); ExitEdit(keepFocus); } } } if (newCurrentItem != null) { slot = this.SlotFromRowIndex(this.DataConnection.IndexOf(newCurrentItem)); } if (slot == -1 && columnIndex != -1) { return false; } this.CurrentColumnIndex = columnIndex; this.CurrentSlot = slot; if (this._temporarilyResetCurrentCell) { if (columnIndex != -1) { this._temporarilyResetCurrentCell = false; } } if (!this._temporarilyResetCurrentCell && this._editingColumnIndex != -1) { this._editingColumnIndex = columnIndex; } if (oldDisplayedElement != null) { DataGridRow row = oldDisplayedElement as DataGridRow; if (row != null) { // Don't reset the state of the current cell if we're editing it because that would put it in an invalid state UpdateCurrentState(oldDisplayedElement, oldCurrentCell.ColumnIndex, !(this._temporarilyResetCurrentCell && row.IsEditing && this._editingColumnIndex == oldCurrentCell.ColumnIndex)); } else { UpdateCurrentState(oldDisplayedElement, oldCurrentCell.ColumnIndex, false /*applyCellState*/); } } if (this.CurrentColumnIndex > -1) { Debug.Assert(this.CurrentSlot > -1); Debug.Assert(this.CurrentColumnIndex < this.ColumnsItemsInternal.Count); Debug.Assert(this.CurrentSlot < this.SlotCount); if (this.IsSlotVisible(this.CurrentSlot)) { UpdateCurrentState(this.DisplayData.GetDisplayedElement(this.CurrentSlot), this.CurrentColumnIndex, true /*applyCellState*/); } } return true; }
private void FlushCurrentCellChanged() { if (this._makeFirstDisplayedCellCurrentCellPending) { return; } if (this.SelectionHasChanged) { // selection is changing, don't raise CurrentCellChanged until it's done this._flushCurrentCellChanged = true; FlushSelectionChanged(); return; } // We don't want to expand all intermediate currency positions, so we only expand // the last current item before we flush the event if (this._collapsedSlotsTable.Contains(this.CurrentSlot)) { DataGridRowGroupInfo rowGroupInfo = this.RowGroupHeadersTable.GetValueAt(this.RowGroupHeadersTable.GetPreviousIndex(this.CurrentSlot)); Debug.Assert(rowGroupInfo != null); if (rowGroupInfo != null) { this.ExpandRowGroupParentChain(rowGroupInfo.Level, rowGroupInfo.Slot); } } if (this.CurrentColumn != this._previousCurrentColumn || this.CurrentItem != this._previousCurrentItem) { this.CoerceSelectedItem(); this._previousCurrentColumn = this.CurrentColumn; this._previousCurrentItem = this.CurrentItem; OnCurrentCellChanged(EventArgs.Empty); } DataGridAutomationPeer peer = DataGridAutomationPeer.FromElement(this) as DataGridAutomationPeer; if (peer != null && this.CurrentCellCoordinates != this._previousAutomationFocusCoordinates) { this._previousAutomationFocusCoordinates = new DataGridCellCoordinates(this.CurrentCellCoordinates); // If the DataGrid itself has focus, we want to move automation focus to the new current element if (FocusManager.GetFocusedElement() == this) { if (AutomationPeer.ListenerExists(AutomationEvents.AutomationFocusChanged)) { peer.RaiseAutomationFocusChangedEvent(this.CurrentSlot, this.CurrentColumnIndex); } } } this._flushCurrentCellChanged = false; }
public DataGrid() { TabNavigation = KeyboardNavigationMode.Once; KeyDown += DataGrid_KeyDown; KeyUp += DataGrid_KeyUp; GotFocus += DataGrid_GotFocus; LostFocus += DataGrid_LostFocus; IsEnabledChanged += DataGrid_IsEnabledChanged; _loadedRows = new List<DataGridRow>(); _selectedItems = new DataGridSelectedItemsCollection(this); _rowGroupHeaderStyles = new ObservableCollection<Style>(); _rowGroupHeaderStyles.CollectionChanged += RowGroupHeaderStyles_CollectionChanged; _rowGroupHeaderStylesOld = new List<Style>(); RowGroupHeadersTable = new IndexToValueTable<DataGridRowGroupInfo>(); _validationResults = new List<ValidationResult>(); DisplayData = new DataGridDisplayData(this); ColumnsInternal = CreateColumnsInstance(); RowHeightEstimate = DATAGRID_defaultRowHeight; RowDetailsHeightEstimate = 0; _rowHeaderDesiredWidth = 0; DataConnection = new DataGridDataConnection(this); _showDetailsTable = new IndexToValueTable<Visibility>(); _collapsedSlotsTable = new IndexToValueTable<Visibility>(); AnchorSlot = -1; _lastEstimatedRow = -1; _editingColumnIndex = -1; _mouseOverRowIndex = null; CurrentCellCoordinates = new DataGridCellCoordinates(-1, -1); RowGroupHeaderHeightEstimate = DATAGRID_defaultRowHeight; DefaultStyleKey = typeof(DataGrid); }
public DataGridCellCoordinates(DataGridCellCoordinates dataGridCellCoordinates) : this(dataGridCellCoordinates.ColumnIndex, dataGridCellCoordinates.RowIndex) { }
internal void InsertRows(int rowIndex, int rowCount) { Debug.Assert(this.ColumnsItemsInternal.Count > 0); Debug.Assert(rowIndex >= 0 && rowIndex <= this.RowCount); Debug.Assert(rowCount == 1); if (RowRequiresDisplay(rowIndex)) { // Row at that index needs to be displayed InsertRow(rowIndex); } else { // Row at that index is off screen DataGridCellCoordinates newCurrentCellCoordinates = new DataGridCellCoordinates(-1, -1); OnInsertingRow(rowIndex, ref newCurrentCellCoordinates, true /*firstInsertion*/, 1 /*insertionCount*/); // will throw an exception if the insertion is illegal this.RowCount++; OnInsertedRow_Phase1(rowIndex, false /*generateRow*/, 1); OnInsertedRow_Phase2(rowIndex, newCurrentCellCoordinates, true /*lastInsertion*/, this._vScrollBar == null || this._vScrollBar.Visibility == Visibility.Visible /*updateVerticalScrollBarOnly*/); OnRowsChanged(true /*rowsGrew*/); } }