/// <summary> /// [email protected]: In UiGrid, we have conditions, were a merged cell chooses to increase the column span (say 2 to 9). /// In this condition, sourcegrid requires user to delete the exisiting cells.So that the merged cell can occupy this portion. /// </summary> private void DeleteCellsExistingInSpannedArea(int row, int col, Cells.ICell cell) { if (AllowOverlappingCells) { return; } for (int y = row; y < row + cell.RowSpan; y++) { for (int x = col; x < col + cell.ColumnSpan; x++) { if (x == col && y == row) { continue; } Cells.ICell existingSpannedCell = DirectGetCell(new Position(y, x)); if (existingSpannedCell != null) { RemoveSpannedCell(new Position(y, x)); DirectSetCell(new Position(y, x), null); } } } }
/// <summary> /// Check /// </summary> private void EnsureNoOtherCellsExist(int row, int col, Cells.ICell p_cell) { for (int y = row; y < row + p_cell.RowSpan; y++) { for (int x = col; x < col + p_cell.ColumnSpan; x++) { if (x == col && y == row) { continue; } Cells.ICell existingSpannedCell = this.DirectGetCell(y, x); if (existingSpannedCell != null) { if (existingSpannedCell != p_cell) { throw new OverlappingCellException(string.Format( "Given cell at position ({0}, {1}), " + "intersects with another cell " + "at position ({2}, {3}) '{4}'", row, col, existingSpannedCell.Row.Index, existingSpannedCell.Column.Index, existingSpannedCell.DisplayText)); } } } } }
private void EnsureNoSpannedCellsExist(int row, int col, Cells.ICell p_cell) { var spanRange = new Range(row, col, row + p_cell.RowSpan - 1, col + p_cell.ColumnSpan - 1); var ranges = spannedCellReferences.SpannedRangesCollection.GetRanges( spanRange); if (ranges.Count == 0) { return; } var start = new Position(row, col); foreach (var range in ranges) { if (start.Equals(range.Start) == true) { continue; } Cells.ICell existingSpannedCell = this[range.Start]; if (existingSpannedCell == null) { throw new ArgumentException("internal error. please report this bug to developers"); } throw new OverlappingCellException(string.Format( "Given cell at position ({0}, {1}), " + "intersects with another cell " + "at position ({2}, {3}) '{4}'", row, col, existingSpannedCell.Row.Index, existingSpannedCell.Column.Index, existingSpannedCell.DisplayText)); } }
private void EnsureDestinationSpannedAreaisCompletelyEmpty(int row, int col, int rowSpan, int colSpan) { if (AllowOverlappingCells) { return; } for (int y = row; y < row + rowSpan; y++) { for (int x = col; x < col + colSpan; x++) { Cells.ICell existingSpannedCell = this[y, x]; if (existingSpannedCell != null) { throw new OverlappingCellException(string.Format( "Given cell at position ({0}, {1}), " + "intersects with another cell " + "at position ({2}, {3}) '{4}'", row, col, (existingSpannedCell.Row != null)?existingSpannedCell.Row.Index : -1, (existingSpannedCell.Column != null)?existingSpannedCell.Column.Index : -1, existingSpannedCell.DisplayText)); } } } }
/// <summary> /// Force a redraw of the specified cell /// </summary> /// <param name="p_Cell"></param> public virtual void InvalidateCell(Cells.ICell p_Cell) { if (p_Cell != null) { base.InvalidateRange(p_Cell.Range); } }
private void Selection_RemovingRange(object sender, RangeRegionCancelEventArgs e) { //se è abilitato RowColSpan devo assicurarmi di selezionare la cella di origine e non quella che sfrutta il RowCol Span if (EnableRowColSpan) { RangeCollection rangesToRemove = e.RangeRegion.GetRanges(); for (int iRange = 0; iRange < rangesToRemove.Count; iRange++) { Range rng = rangesToRemove[iRange]; for (int r = rng.Start.Row; r <= rng.End.Row; r++) { for (int c = rng.Start.Column; c <= rng.End.Column; c++) { Cells.ICell l_Cell = this[r, c]; //N.B. questo metodo mi restituisce la cella reale (anche se questa posizione è occupata slo perchè in mee con Row/Col Span) if (l_Cell != null) { Range l_Range = l_Cell.Range; if (l_Range != new Range(new Position(r, c))) //se la cella occupa più righe o colonne { e.RangeRegion.Add(l_Range); //la seleziono tutta } } } } } } }
//[email protected] : Getting the correct row span. Previous implementation // was not considering the row sapn of current row header private static int GetRowSpan(Cells.ICell cell, int startIndex, int count) { const int defaultRowSpan = 1; if (cell == null) { return(defaultRowSpan); } int endIndex = startIndex + count - 1; int startSpannedIndex = cell.Range.Start.Row; int endSpannedIndex = cell.Range.End.Row; int rowSpan = cell.RowSpan; if (startSpannedIndex >= startIndex) { return(rowSpan); } if (endSpannedIndex < endIndex) { return(startIndex - startSpannedIndex); } rowSpan = rowSpan - count; return(rowSpan); }
private void DirectSetCell(Position position, Cells.ICell cell) { if (OptimizeMode == CellOptimizeMode.ForRows) { GridRow row = Rows[position.Row]; if (position.Column >= Columns.Count) { throw new ArgumentException(string.Format( "Grid has only {0} columns, you tried to insert cell into position {1}." + "You should probably call Redim on grid to increase it's column size", Columns.Count, position.ToString())); } row[Columns[position.Column] as GridColumn] = cell; } else if (OptimizeMode == CellOptimizeMode.ForColumns) { GridColumn col = Columns[position.Column] as GridColumn; col[Rows[position.Row]] = cell; } else { throw new SourceGridException("Invalid OptimizeMode"); } }
/// <summary> /// Set the focus to the specified cell (the specified cell became the active cell, FocusCell property). /// </summary> /// <param name="p_CellToSetFocus"></param> /// <returns></returns> public bool SetFocusCell(Cells.ICell p_CellToSetFocus) { if (p_CellToSetFocus == null) { return(Selection.Focus(Position.Empty)); } else { return(Selection.Focus(p_CellToSetFocus.Range.Start)); } }
/// <summary> /// Scroll the view to show the specified cell /// </summary> /// <param name="p_CellToShow"></param> /// <returns></returns> public bool ShowCell(Cells.ICell p_CellToShow) { if (p_CellToShow != null) { return(base.ShowCell(p_CellToShow.Range.Start)); } else { return(true); } }
/// <summary> /// Remove the specified cell /// </summary> /// <param name="row"></param> /// <param name="col"></param> private void RemoveCell(int row, int col) { Cells.ICell tmp = DirectGetCell(new Position(row, col)); if (tmp != null) { tmp.UnBindToGrid(); DirectSetCell(new Position(row, col), null); } }
/// <summary> /// Returns true if the specified cell is visible otherwise false /// </summary> /// <param name="p_Cell"></param> /// <returns></returns> public bool IsCellVisible(Cells.ICell p_Cell) { if (p_Cell != null) { return(base.IsCellVisible(p_Cell.Range.Start)); } else { return(true); } }
/// <summary> /// Force a cell to redraw. If Redraw is set to false this function has no effects. If ColSpan or RowSpan is greater than 0 this function invalidate the complete range with InvalidateRange /// </summary> /// <param name="p_Position"></param> public override void InvalidateCell(Position p_Position) { Cells.ICell l_Cell = this[p_Position.Row, p_Position.Column]; if (l_Cell == null) { base.InvalidateCell(p_Position); } else { InvalidateRange(l_Cell.Range); } }
/// <summary> /// Force a cell to redraw. If ColSpan or RowSpan is greater than 0 this function invalidate the complete range with InvalidateRange /// </summary> /// <param name="p_Position"></param> public override void InvalidateCell(Position p_Position) { Cells.ICell cell = this[p_Position.Row, p_Position.Column]; if (cell == null || (cell.Range.ColumnsCount == 1 && cell.Range.RowsCount == 1)) { base.InvalidateCell(p_Position); } else { InvalidateRange(cell.Range); } }
public override Size PositionToSize(Position position) { Cells.ICell cell = this[position.Row, position.Column]; if (cell != null) { return(base.RangeToRectangle(cell.Range).Size); } else { return(base.PositionToSize(position)); } }
/// <summary> /// Get the Rectangle of the cell respect all the scrollable area. Using the Cell Row/Col Span. /// </summary> /// <param name="position"></param> /// <returns></returns> public override Rectangle PositionToRectangleRelative(int?relativeRow, int?relativeCol, Position position) { Cells.ICell cell = this[position.Row, position.Column]; if (cell != null) { return(RangeToRectangleRelative(relativeRow, relativeCol, cell.Range)); } else { return(base.PositionToRectangleRelative(relativeRow, relativeCol, position)); } }
/// <summary> /// Remove the specified cell /// </summary> /// <param name="row"></param> /// <param name="col"></param> private void RemoveCell(int row, int col) { Cells.ICell cell = DirectGetCell(new Position(row, col)); if (cell == null) { return; } cell.UnBindToGrid(); RemoveSpannedCell(new Position(row, col)); DirectSetCell(new Position(row, col), null); }
/// <summary> /// Insert the specified cell /// </summary> /// <param name="row"></param> /// <param name="col"></param> /// <param name="p_cell"></param> private void InsertCell(int row, int col, Cells.ICell p_cell) { RemoveCell(row, col); if (p_cell != null && p_cell.Grid != null) { throw new ArgumentException("This cell already have a linked grid", "p_cell"); } DirectSetCell(new Position(row, col), p_cell); if (p_cell != null) { p_cell.BindToGrid(this, new Position(row, col)); } }
public Cells.ICell this[Position position] { get { Cells.ICell cell = DirectGetCell(position); if (cell != null) { return(cell); } return(GetSpannedCell(position)); } set { InsertCell(position.Row, position.Column, value); } }
/// <summary> /// This method converts a Position to the real range of the cell. This is usefull when RowSpan or ColumnSpan is greater than 1. /// For example suppose to have at grid[0,0] a cell with ColumnSpan equal to 2. If you call this method with the position 0,0 returns 0,0-0,1 and if you call this method with 0,1 return again 0,0-0,1. /// </summary> /// <param name="pPosition"></param> /// <returns></returns> public override Range PositionToCellRange(Position pPosition) { if (pPosition.IsEmpty()) { return(Range.Empty); } Cells.ICell l_Cell = this[pPosition.Row, pPosition.Column]; if (l_Cell == null) { return(new Range(pPosition)); } else { return(l_Cell.Range); } }
private void m_Columns_ColumnsRemoved(object sender, IndexRangeEventArgs e) { //N.B. Uso m_Cells.GetLength(0) anziche' RowsCount e // m_Cells.GetLength(1) anziche' ColumnsCount per essere sicuro di lavorare sulle righe effetivamente allocate for (int c = (e.StartIndex + e.Count); c < CellsCols; c++) { for (int r = 0; r < CellsRows; r++) { Cells.ICell tmp = m_Cells[r, c]; RemoveCell(r, c); InsertCell(r, c - e.Count, tmp); } } RedimCellsMatrix(CellsRows, CellsCols - e.Count); }
/// <summary> /// Insert the specified cell (for best performance set Redraw property to false) /// </summary> /// <param name="row"></param> /// <param name="col"></param> /// <param name="p_cell"></param> public virtual void InsertCell(int row, int col, Cells.ICell p_cell) { RemoveCell(row, col); m_Cells[row, col] = p_cell; if (p_cell != null) { if (p_cell.Grid != null) { throw new ArgumentException("This cell already have a linked grid", "p_cell"); } p_cell.BindToGrid(this, new Position(row, col)); p_cell.Invalidate(); } }
private void m_Columns_ColumnsAdded(object sender, IndexRangeEventArgs e) { //N.B. Uso m_Cells.GetLength(0) anziche' RowsCount e // m_Cells.GetLength(1) anziche' ColumnsCount per essere sicuro di lavorare sulle righe effetivamente allocate RedimCellsMatrix(CellsRows, CellsCols + e.Count); //dopo aver ridimensionato la matrice sposto le celle in modo da fare spazio alla nuove righe for (int c = CellsCols - 1; c > (e.StartIndex + e.Count - 1); c--) { for (int r = 0; r < CellsRows; r++) { Cells.ICell tmp = m_Cells[r, c - e.Count]; RemoveCell(r, c - e.Count); InsertCell(r, c, tmp); } } }
///// <summary> ///// Array of cells ///// </summary> //private Cells.ICell[,] m_Cells = null; //private int CellsRows //{ // get // { // if (m_Cells==null) // return 0; // else // return m_Cells.GetLength(0); // } //} //private int CellsCols //{ // get // { // if (m_Cells==null) // return 0; // else // return m_Cells.GetLength(1); // } //} private void DirectSetCell(Position position, Cells.ICell cell) { if (OptimizeMode == CellOptimizeMode.ForRows) { GridRow row = Rows[position.Row]; row[Columns[position.Column]] = cell; } else if (OptimizeMode == CellOptimizeMode.ForColumns) { GridColumn col = Columns[position.Column]; col[Rows[position.Row]] = cell; } else { throw new SourceGridException("Invalid OptimizeMode"); } }
/// <summary> /// Check if a cell exists in spanned cells. /// If yes, returns. If no, returns null /// </summary> private Cells.ICell GetSpannedCell(Position pos) { var range = spannedCellReferences.SpannedRangesCollection.GetFirstIntersectedRange(pos); if (range == null) { return(null); } Position cellPos = range.Value.Start; Cells.ICell cell = DirectGetCell(cellPos); if (cell == null) { throw new ArgumentException(string.Format( "Invalid grid state. Grid should contain a spanned cell at position {0}, " + " but apparently it does not!", cellPos)); } return(cell); }
/// <summary> /// Remove the specified cell /// </summary> /// <param name="row"></param> /// <param name="col"></param> public virtual void RemoveCell(int row, int col) { Cells.ICell tmp = m_Cells[row, col]; if (tmp != null) { #if !MINI //se per caso la cella era quella correntemente con il mouse metta quest'ultima a null if (tmp == MouseCell) { ChangeMouseCell(Position.Empty); } #endif tmp.Select = false; //deseleziono la cella (per evitare che venga rimossa senza essere stata aggiunta alla lista di selection tmp.LeaveFocus(); //tolgo l'eventuale focus dalla cella tmp.UnBindToGrid(); m_Cells[row, col] = null; } }
/// <summary> /// Returns all the cells at specified column position /// </summary> /// <param name="p_ColumnIndex"></param> /// <returns></returns> public override Cells.ICellVirtual[] GetCellsAtColumn(int p_ColumnIndex) { Cells.ICellVirtual[] l_Cells = new Cells.ICellVirtual[Rows.Count]; for (int r = 0; r < Rows.Count;) { Cells.ICell l_Cell = this[r, p_ColumnIndex]; if (l_Cell != null && l_Cell.Range.Start == new Position(r, p_ColumnIndex)) { l_Cells[r] = l_Cell; r += l_Cell.RowSpan; } else { l_Cells[r] = null; r++; } } return(l_Cells); }
/// <summary> /// Returns all the cells at specified row position /// </summary> /// <param name="p_RowIndex"></param> /// <returns></returns> public override Cells.ICellVirtual[] GetCellsAtRow(int p_RowIndex) { Cells.ICellVirtual[] l_Cells = new Cells.ICellVirtual[Columns.Count]; for (int c = 0; c < Columns.Count;) { Cells.ICell l_Cell = this[p_RowIndex, c]; if (l_Cell != null && l_Cell.Range.Start == new Position(p_RowIndex, c)) { l_Cells[c] = l_Cell; c += l_Cell.ColumnSpan; } else { l_Cells[c] = null; c++; } } return(l_Cells); }
private void DirectSetCell(Position position, Cells.ICell cell) { //[email protected]: Error check done first. if (position.Column >= Columns.Count) { throw new ArgumentException(string.Format( "Grid has only {0} columns, you tried to insert cell into position {1}." + "You should probably call Redim on grid to increase it's column size", Columns.Count, position.ToString())); } GridColumn col = Columns[position.Column] as GridColumn; if (col == null) { return; } GridRow row = Rows[position.Row]; if (row == null) { return; } if (OptimizeMode == CellOptimizeMode.ForRows) { row[col] = cell; } else if (OptimizeMode == CellOptimizeMode.ForColumns) { col[row] = cell; } else { throw new SourceGridException("Invalid OptimizeMode"); } }
/// <summary> /// Fired when calling SortRangeRows method. If the range contains all the columns this method move directly the row object otherwise move each cell. /// </summary> /// <param name="e"></param> protected override void OnSortingRangeRows(SortRangeRowsEventArgs e) { base.OnSortingRangeRows(e); if (CustomSort) return; if (e.KeyColumn > e.Range.End.Column && e.KeyColumn < e.Range.Start.Column) throw new ArgumentException("Invalid range", "e.KeyColumn"); System.Collections.IComparer cellComparer = e.CellComparer; if (cellComparer == null) cellComparer = new ValueCellComparer(); //Sort all the columns (in this case I move directly the row object) if (e.Range.ColumnsCount == ColumnsCount) { RowInfo[] rowInfoToSort = new RowInfo[e.Range.End.Row-e.Range.Start.Row+1]; Cells.ICell[] cellKeys = new Cells.ICell[e.Range.End.Row-e.Range.Start.Row+1]; int zeroIndex = 0; for (int r = e.Range.Start.Row; r <= e.Range.End.Row;r++) { cellKeys[zeroIndex] = this[r, e.KeyColumn]; rowInfoToSort[zeroIndex] = Rows[r]; zeroIndex++; } Array.Sort(cellKeys, rowInfoToSort, 0, cellKeys.Length, cellComparer); //Apply sort if (e.Ascending) { for (zeroIndex = 0; zeroIndex < rowInfoToSort.Length; zeroIndex++) { Rows.Swap( rowInfoToSort[zeroIndex].Index, e.Range.Start.Row + zeroIndex); } } else //desc { for (zeroIndex = rowInfoToSort.Length-1; zeroIndex >= 0; zeroIndex--) { Rows.Swap( rowInfoToSort[zeroIndex].Index, e.Range.End.Row - zeroIndex); } } } else //sort only the specified range { Cells.ICell[][] l_RangeSort = new Cells.ICell[e.Range.End.Row-e.Range.Start.Row+1][]; Cells.ICell[] l_CellsKeys = new Cells.ICell[e.Range.End.Row-e.Range.Start.Row+1]; int zeroRowIndex = 0; for (int r = e.Range.Start.Row; r <= e.Range.End.Row;r++) { l_CellsKeys[zeroRowIndex] = this[r, e.KeyColumn]; int zeroColIndex = 0; l_RangeSort[zeroRowIndex] = new Cells.ICell[e.Range.End.Column-e.Range.Start.Column+1]; for (int c = e.Range.Start.Column; c <= e.Range.End.Column; c++) { l_RangeSort[zeroRowIndex][zeroColIndex] = this[r,c]; zeroColIndex++; } zeroRowIndex++; } Array.Sort(l_CellsKeys, l_RangeSort, 0, l_CellsKeys.Length, cellComparer); //Apply sort zeroRowIndex = 0; if (e.Ascending) { for (int r = e.Range.Start.Row; r <= e.Range.End.Row;r++) { int zeroColIndex = 0; for (int c = e.Range.Start.Column; c <= e.Range.End.Column; c++) { RemoveCell(r,c);//rimuovo qualunque cella nella posizione corrente Cells.ICell tmp = l_RangeSort[zeroRowIndex][zeroColIndex]; if (tmp!=null && tmp.Grid!=null && tmp.Range.Start.Row>=0 && tmp.Range.Start.Column>=0) //verifico che la cella sia valida RemoveCell(tmp.Range.Start.Row, tmp.Range.Start.Column);//la rimuovo dalla posizione precedente this[r,c] = tmp; zeroColIndex++; } zeroRowIndex++; } } else //desc { for (int r = e.Range.End.Row; r >= e.Range.Start.Row;r--) { int zeroColIndex = 0; for (int c = e.Range.Start.Column; c <= e.Range.End.Column; c++) { RemoveCell(r,c);//rimuovo qualunque cella nella posizione corrente Cells.ICell tmp = l_RangeSort[zeroRowIndex][zeroColIndex]; if (tmp!=null && tmp.Grid!=null && tmp.Range.Start.Row >= 0 && tmp.Range.Start.Column >= 0) //verifico che la cella sia valida RemoveCell(tmp.Range.Start.Row, tmp.Range.Start.Column);//la rimuovo dalla posizione precedente this[r,c] = tmp; zeroColIndex++; } zeroRowIndex++; } } } }
/// <summary> /// Fired when calling SortRangeRows method. If the range contains all the columns this method move directly the row object otherwise move each cell. /// </summary> /// <param name="e"></param> protected override void OnSortingRangeRows(SortRangeRowsEventArgs e) { base.OnSortingRangeRows(e); if (CustomSort) { return; } if (e.KeyColumn > e.Range.End.Column && e.KeyColumn < e.Range.Start.Column) { throw new ArgumentException("Invalid range", "e.KeyColumn"); } System.Collections.IComparer cellComparer = e.CellComparer; if (cellComparer == null) { cellComparer = new ValueCellComparer(); } //Sort all the columns (in this case I move directly the row object) if (e.Range.ColumnsCount == ColumnsCount) { RowInfo[] rowInfoToSort = new RowInfo[e.Range.End.Row - e.Range.Start.Row + 1]; Cells.ICell[] cellKeys = new Cells.ICell[e.Range.End.Row - e.Range.Start.Row + 1]; int zeroIndex = 0; for (int r = e.Range.Start.Row; r <= e.Range.End.Row; r++) { cellKeys[zeroIndex] = this[r, e.KeyColumn]; rowInfoToSort[zeroIndex] = Rows[r]; zeroIndex++; } Array.Sort(cellKeys, rowInfoToSort, 0, cellKeys.Length, cellComparer); //Apply sort if (e.Ascending) { for (zeroIndex = 0; zeroIndex < rowInfoToSort.Length; zeroIndex++) { Rows.Swap(rowInfoToSort[zeroIndex].Index, e.Range.Start.Row + zeroIndex); } } else //desc { for (zeroIndex = rowInfoToSort.Length - 1; zeroIndex >= 0; zeroIndex--) { Rows.Swap(rowInfoToSort[zeroIndex].Index, e.Range.End.Row - zeroIndex); } } } else //sort only the specified range { Cells.ICell[][] l_RangeSort = new Cells.ICell[e.Range.End.Row - e.Range.Start.Row + 1][]; Cells.ICell[] l_CellsKeys = new Cells.ICell[e.Range.End.Row - e.Range.Start.Row + 1]; int zeroRowIndex = 0; for (int r = e.Range.Start.Row; r <= e.Range.End.Row; r++) { l_CellsKeys[zeroRowIndex] = this[r, e.KeyColumn]; int zeroColIndex = 0; l_RangeSort[zeroRowIndex] = new Cells.ICell[e.Range.End.Column - e.Range.Start.Column + 1]; for (int c = e.Range.Start.Column; c <= e.Range.End.Column; c++) { l_RangeSort[zeroRowIndex][zeroColIndex] = this[r, c]; zeroColIndex++; } zeroRowIndex++; } Array.Sort(l_CellsKeys, l_RangeSort, 0, l_CellsKeys.Length, cellComparer); //Apply sort zeroRowIndex = 0; if (e.Ascending) { for (int r = e.Range.Start.Row; r <= e.Range.End.Row; r++) { int zeroColIndex = 0; for (int c = e.Range.Start.Column; c <= e.Range.End.Column; c++) { RemoveCell(r, c); //rimuovo qualunque cella nella posizione corrente Cells.ICell tmp = l_RangeSort[zeroRowIndex][zeroColIndex]; if (tmp != null && tmp.Grid != null && tmp.Range.Start.Row >= 0 && tmp.Range.Start.Column >= 0) //verifico che la cella sia valida { RemoveCell(tmp.Range.Start.Row, tmp.Range.Start.Column); //la rimuovo dalla posizione precedente } this[r, c] = tmp; zeroColIndex++; } zeroRowIndex++; } } else //desc { for (int r = e.Range.End.Row; r >= e.Range.Start.Row; r--) { int zeroColIndex = 0; for (int c = e.Range.Start.Column; c <= e.Range.End.Column; c++) { RemoveCell(r, c); //rimuovo qualunque cella nella posizione corrente Cells.ICell tmp = l_RangeSort[zeroRowIndex][zeroColIndex]; if (tmp != null && tmp.Grid != null && tmp.Range.Start.Row >= 0 && tmp.Range.Start.Column >= 0) //verifico che la cella sia valida { RemoveCell(tmp.Range.Start.Row, tmp.Range.Start.Column); //la rimuovo dalla posizione precedente } this[r, c] = tmp; zeroColIndex++; } zeroRowIndex++; } } } }