/// <summary> /// Constructor /// </summary> /// <param name="p_StartRow"></param> /// <param name="p_StartCol"></param> /// <param name="p_EndRow"></param> /// <param name="p_EndCol"></param> public Range(int p_StartRow, int p_StartCol, int p_EndRow, int p_EndCol) { m_Start = new Position(p_StartRow, p_StartCol); m_End = new Position(p_EndRow, p_EndCol); Normalize(); }
public static Range From(Position startPosition, int rowCount, int colCount) { var range = new Range(startPosition); range.RowsCount = rowCount; range.ColumnsCount = colCount; return range; }
public Range? GetFirstIntersectedRange(Position pos) { var result = base.QueryFirst(pos); if (result == null) return null; return result; }
/// <summary> /// Move the current range to the specified position, leaving the current ColumnsCount and RowsCount /// </summary> /// <param name="p_StartPosition"></param> public void MoveTo(Position p_StartPosition) { int l_ColCount = ColumnsCount; int l_RowCount = RowsCount; m_Start = p_StartPosition; RowsCount = l_RowCount; ColumnsCount = l_ColCount; }
private Range(Position p_Start, Position p_End, bool p_bCheck) { m_Start = p_Start; m_End = p_End; if (p_bCheck) Normalize(); }
/// <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 Range.Empty; else return l_Cell.Range; }
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)); } }
/// <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; }
private Cells.ICell DirectGetCell(Position position) { if (IsInGrid(position) == false) return null; if (OptimizeMode == CellOptimizeMode.ForRows) { GridRow row = Rows[position.Row]; if (row == null) return null; return row[Columns[position.Column] as GridColumn]; } else if (OptimizeMode == CellOptimizeMode.ForColumns) { GridColumn col = Columns[position.Column] as GridColumn; if (col == null) return null; return col[Rows[position.Row]]; } else throw new SourceGridException("Invalid OptimizeMode"); }
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> /// Constructor /// </summary> /// <param name="pGridVirtual"></param> /// <param name="pPosition"></param> public CellContext(GridVirtual pGridVirtual, Position pPosition) { Position = pPosition; Grid = pGridVirtual; Cell = Grid.GetCell(Position); }
/// <summary> /// Fired when the cell in the drag events change. For internal use only. /// </summary> /// <param name="cell"></param> /// <param name="pDragEventArgs"></param> public virtual void ChangeDragCell(CellContext cell, DragEventArgs pDragEventArgs) { if (cell.Position != mDragCellPosition) { if (mDragCellPosition.IsEmpty() == false) Controller.OnDragLeave(new CellContext(this, mDragCellPosition, GetCell(mDragCellPosition)), pDragEventArgs); if (cell.Position.IsEmpty() == false) Controller.OnDragEnter(cell, pDragEventArgs); mDragCellPosition = cell.Position; } }
int FindFirstFocusableRowInDownDirection(int TopRow) { for (int k = TopRow; k < Rows.Count; k++) { Position newPosition = new Position(k, Selection.ActivePosition.Column); if (Selection.CanReceiveFocus(newPosition)) return k; } return -1; }
public override void CustomScrollPageDown() { bool NeedActualScrolling=false; int NewProposedTopRow=0; int NewProposedFocusedRow=0; Range rngFocusedCell = PositionToCellRange(Selection.ActivePosition); //if there is no selection here (ActiveRow is undefined), //put selection in the first possible cell //confusing NAMING: Rows.IsRowVisible -> Rows.NotHidden - because it is not hidden, // may be confused with visible on screen within visible page if (rngFocusedCell.IsEmpty()) { Selection.MoveActiveCell(1, 0); return; } List<int> rows = GetVisibleRows(false); if (rows.Count <= ActualFixedRows + 1) { Selection.MoveActiveCell(1, 0); return; }; int firstVisibleRow = rows[ActualFixedRows]; int lastVisibleRow = rows[rows.Count - 1]; // AlanP: Sep 2013 We need to know if SHIFT is pressed bool shiftPressed = Control.ModifierKeys == Keys.Shift; if (IsThisRowVisibleOnScreen(rngFocusedCell.Start.Row)) { //focus is on the screen int BottommostFocusableRow = GetBottommostFocusableRowFromRange(firstVisibleRow, lastVisibleRow); if (rngFocusedCell.ContainsRow(BottommostFocusableRow)) { //need actual scrolling, ie. displaying new page int FindFirstFocusableRow = FindFirstFocusableRowInDownDirection(lastVisibleRow); if (FindFirstFocusableRow != -1) { NeedActualScrolling = true; NewProposedTopRow = lastVisibleRow; int NewProposedBottomRow = GetBottomVisibleRowFromTopRow(NewProposedTopRow); NewProposedFocusedRow = GetBottommostFocusableRowFromRange(NewProposedTopRow, NewProposedBottomRow); if (NewProposedFocusedRow == -1) {//There is no Focusable Row in the proposed page, so there need to be new page and focus found NewProposedFocusedRow = FindFirstFocusableRowInDownDirection(NewProposedBottomRow); NewProposedTopRow = GetTopVisibleRowFromBottomRow(NewProposedFocusedRow); } } else { //no focusable cells below - //in this case we might scroll down page, leaving focus unchanged //or move focus to the side like in arrow down handler //this is only temporary //MICK(23) Selection.MoveActiveCell(1, 0); return; } } else { //this time only move focus, wihout actual scrolling Position newPosition = new Position(BottommostFocusableRow, Selection.ActivePosition.Column); // AlanP: Sep 2013 We inhibit change events if SHIFT is pressed because we still have more calls to do Selection.Focus(newPosition, true, shiftPressed); } } else {// focus is not on the screen, so actual scrolling is done always NeedActualScrolling = true; NewProposedTopRow = rngFocusedCell.Start.Row; int NewProposedBottomRow = GetBottomVisibleRowFromTopRow(NewProposedTopRow); NewProposedFocusedRow = GetBottommostFocusableRowFromRange(NewProposedTopRow, NewProposedBottomRow); } if (NeedActualScrolling) { int NewTopRow=0; int NewFocusedRow=0; GetValidScrollDown(NewProposedTopRow, NewProposedFocusedRow, out NewTopRow, out NewFocusedRow); NewTopRow = ExtendTopRowByHiddenRows(NewTopRow); base.CustomScrollPageToLine(NewTopRow - ActualFixedRows); if (rngFocusedCell.ContainsRow(NewFocusedRow) == false) { Position newPosition = new Position(NewFocusedRow, Selection.ActivePosition.Column); // AlanP: Sep 2013 We inhibit change events if SHIFT is pressed because we still have more calls to do Selection.Focus(newPosition, true, shiftPressed); } } }
public override void CustomScrollPageUp() { bool NeedActualScrolling=false; int NewProposedTopRow=0; int NewProposedFocusedRow=0; //confusing NAMING: ActivePosition -> FocusedPosition - it would be better int FocusedRow = Selection.ActivePosition.Row; //TODO: if there is no selection here (ActiveRow is undefined), //put selection in the first possible cell //confusing NAMING: Rows.IsRowVisible -> Rows.NotHidden - because it is not hidden, // may be confused with visible on screen within visible page if (FocusedRow == -1) { Selection.MoveActiveCell(-1, 0); return; } List<int> rows = GetVisibleRows(false); //TODO: if Rows.height<displayheight if (rows.Count <= ActualFixedRows + 1) { Selection.MoveActiveCell(-1, 0); return; }; int firstVisibleRow = rows[ActualFixedRows]; int lastVisibleRow = rows[rows.Count - 1]; //another workaround: if (focusedrow==firstVisibleRow) //if the row above has height larger than displayheight it is also like one row scrolling- //so workaround is needed like the one above if (FocusedRow == firstVisibleRow) if (FocusedRow>ActualFixedRows) { int displayHeight = DisplayRectangle.Height; //Remove the fixed rows from the scrollable area for (int f = 0; f < ActualFixedRows; f++) displayHeight -= Rows.GetHeight(f); if (displayHeight <= Rows.GetHeight(FocusedRow - 1)) { Selection.MoveActiveCell(-1, 0); return; } } // AlanP: Sep 2013 We need to know if SHIFT is pressed bool shiftPressed = Control.ModifierKeys == Keys.Shift; if (IsThisRowVisibleOnScreen(FocusedRow)) { //focus is on the screen int TopmostFocusableRow = GetTopmostFocusableRowFromRange(firstVisibleRow, lastVisibleRow); if (TopmostFocusableRow == FocusedRow) { //need actual scrolling, ie. displaying new page int FindFirstFocusableRow = FindFirstFocusableRowInUpDirection(firstVisibleRow); if (FindFirstFocusableRow != -1) { NeedActualScrolling = true; int NewProposedBottomRow = firstVisibleRow; NewProposedTopRow = GetTopVisibleRowFromBottomRow(NewProposedBottomRow); NewProposedFocusedRow = GetTopmostFocusableRowFromRange(NewProposedTopRow, NewProposedBottomRow); if (NewProposedFocusedRow == -1) {//There is no Focusable Row in the proposed page, so there need to be new page and focus found NewProposedFocusedRow = FindFirstFocusableRowInUpDirection(NewProposedTopRow); NewProposedTopRow = NewProposedFocusedRow; } } else { //no focusable cells below - //in this case we might scroll down page, leaving focus unchanged //or move focus to the side like in arrow down handler //this is only temporary //MICK(24) Selection.MoveActiveCell(-1, 0); return; } } else { //this time only move focus, wihout actual scrolling Position newPosition = new Position(TopmostFocusableRow, Selection.ActivePosition.Column); // AlanP: Sep 2013 We inhibit change events if SHIFT is pressed because we still have more calls to do Selection.Focus(newPosition, true, shiftPressed); } } else {// focus is not on the screen, so actual scrolling is done always NeedActualScrolling = true; int NewProposedBottomRow = FocusedRow; NewProposedTopRow = GetTopVisibleRowFromBottomRow(NewProposedBottomRow); NewProposedFocusedRow = GetTopmostFocusableRowFromRange(NewProposedTopRow, NewProposedBottomRow); //NewProposedTopRow = FocusedRow; //NewProposedFocusedRow = GetBottomVisibleRowFromTopRow(NewProposedTopRow); } if (NeedActualScrolling) { int NewTopRow=0; int NewFocusedRow=0; GetValidScrollUp(NewProposedTopRow, NewProposedFocusedRow, out NewTopRow, out NewFocusedRow); NewTopRow = ExtendTopRowByHiddenRows(NewTopRow); base.CustomScrollPageToLine(NewTopRow - ActualFixedRows); if (NewFocusedRow != FocusedRow) { Position newPosition = new Position(NewFocusedRow, Selection.ActivePosition.Column); // AlanP: Sep 2013 We inhibit change events if SHIFT is pressed because we still have more calls to do Selection.Focus(newPosition, true, shiftPressed); } } }
/// <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 virtual Range PositionToCellRange(Position pPosition) { if (pPosition.IsEmpty()) return Range.Empty; ICellVirtual l_Cell = this.GetCell(pPosition.Row, pPosition.Column); if (l_Cell == null) return Range.Empty; else return new Range(pPosition); //return new Range(pPosition); }
int FindFirstFocusableRowInUpDirection(int BottomRow) { for (int k = BottomRow; k > ActualFixedRows; k--) { Position newPosition = new Position(k, Selection.ActivePosition.Column); if (Selection.CanReceiveFocus(newPosition)) return k; } return -1; }
/// <summary> /// Constructor /// </summary> /// <param name="pGridVirtual"></param> /// <param name="pPosition"></param> /// <param name="pCell"></param> public CellContext(GridVirtual pGridVirtual, Position pPosition, Cells.ICellVirtual pCell) { Position = pPosition; Cell = pCell; Grid = pGridVirtual; }
int GetTopmostFocusableRowFromRange(int firstRow, int lastRow) { for (int k = firstRow; k <= lastRow; k++) { Position newPosition = new Position(k, Selection.ActivePosition.Column); if (Selection.CanReceiveFocus(newPosition)) return k; } return -1; }
/// <summary> /// Set the specified cell int he specified position. This method calls SetCell(int p_iRow, int p_iCol, Cells.ICellVirtual p_Cell) /// </summary> /// <param name="p_Position"></param> /// <param name="p_Cell"></param> public void SetCell(Position p_Position, Cells.ICellVirtual p_Cell) { SetCell(p_Position.Row, p_Position.Column, p_Cell); }
/// <summary> /// Indicates if the specified cell is visible. /// </summary> /// <param name="position"></param> /// <param name="partial">True to returns also partial visible cells</param> /// <returns></returns> public bool IsCellVisible(Position position, bool partial) { Point scrollPosition; return !(GetScrollPositionToShowCell(position, partial, out scrollPosition)); }
private bool IsInGrid(Position position) { if (position.Column < 0) return false; if (position.Row < 0 ) return false; if (position.Column >= this.Columns.Count) return false; if (position.Row >= this.Rows.Count) return false; return true; }
///// <summary> ///// Indicates if the specified range is visible ///// </summary> ///// <param name="range"></param> ///// <param name="partial">True to return also partial visible cells</param> ///// <returns></returns> //public bool IsRangeVisible(Range range, bool partial) //{ // List<int> rows = GetVisibleRows(partial); // List<int> columns = GetVisibleColumns(partial); // if (rows.Count == 0 || columns.Count == 0) // return false; // //All the fixed rows are considered to be visible // bool isRowVisible = false; // if (range.Start.Row < FixedRows) // isRowVisible = true; // else if (range.Start.Row <= rows[rows.Count - 1] && // range.End.Row >= rows[0]) // isRowVisible = true; // bool isColVisible = false; // if (range.Start.Column < FixedColumns) // isColVisible = true; // else if (range.Start.Column <= columns[columns.Count - 1] && // range.End.Column >= columns[0]) // isColVisible = true; // return isColVisible && isRowVisible; //} /// <summary> /// Return the scroll position that must be set to show a specific cell. /// </summary> /// <param name="position"></param> /// <param name="partial">True to consider also partial visible cells</param> /// <param name="newScrollPosition"></param> /// <returns>Return false if the cell is already visible, return true is the cell is not currently visible.</returns> protected virtual bool GetScrollPositionToShowCell(Position position, bool partial, out Point newScrollPosition) { Rectangle displayRectangle = DisplayRectangle; List<int> rows = GetVisibleRows(partial); List<int> columns = GetVisibleColumns(partial); if (rows.Contains(position.Row) && columns.Contains(position.Column)) { newScrollPosition = CustomScrollPosition; return false; } else { CellPositionType posType = GetPositionType(position); bool isFixedTop = false; if (posType == CellPositionType.FixedTop || posType == CellPositionType.FixedTopLeft) isFixedTop = true; bool isFixedLeft = false; if (posType == CellPositionType.FixedLeft || posType == CellPositionType.FixedTopLeft) isFixedLeft = true; int x; if (columns.Contains(position.Column)) //Is x visible { x = CustomScrollPosition.X; } else { if (isFixedLeft) x = 0; else x = position.Column - FixedColumns; //Check if the scrollable positioin if not outside the valid area int maxX = GetScrollColumns(displayRectangle.Width); if (x > maxX) x = maxX; } int y; if (rows.Contains(position.Row)) //Is y visible { y = CustomScrollPosition.Y; y = ExtendTopRowByHiddenRows(y); } else { //MICK(15): add direction dependent procedure of finding y (and x should be too). //It means that when you go from bottom to top, the selected item will be at top, // (this already happens, so this part is not changed) // when you go from top to bottom, the selected item will be at bottom, // y (and x) value is adjusted accordingly if (CustomScrollPosition.Y + ActualFixedRows > position.Row) { //MICK(16): direction bottom to top if (isFixedTop) y = 0; else y = position.Row - FixedRows; //Check if the scrollable positioin if not outside the valid area int maxY = GetScrollRows(displayRectangle.Height); if (y > maxY) y = maxY; //MICK(21) y=ExtendTopRowByHiddenRows(y); } else { //MICK(17): direction from top to bottom y = GetTopVisibleRowFromBottomRow(position.Row) - ActualFixedRows; y = ExtendTopRowByHiddenRows(y); } } newScrollPosition = new Point(x, y); return true; } }
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> /// Scroll the view to show the cell passed. Ensure that if the cell if invisible or partial visible it will be totally visible /// </summary> /// <param name="p_Position"></param> /// <param name="ignorePartial">true to ignore and consider already visible partial visible cells</param> /// <returns>Returns true if the Cell passed was already visible, otherwise false</returns> public bool ShowCell(Position p_Position, bool ignorePartial) { Point l_newCustomScrollPosition; if (GetScrollPositionToShowCell(p_Position, ignorePartial, out l_newCustomScrollPosition)) { CustomScrollPosition = l_newCustomScrollPosition; //il problema di refresh si verifica solo in caso di FixedRows e ColumnsCount maggiori di 0 if (FixedRows > 0 || FixedColumns > 0) Invalidate(); return false; } return true; }
/// <summary> /// Removes a spanned cell internal reference. /// This effectively removes any data in spannedCellReferences collection /// </summary> /// <param name="pos"></param> private void RemoveSpannedCell(Position pos) { var range = spannedCellReferences.SpannedRangesCollection.GetFirstIntersectedRange(pos); if (range == null ) return; spannedCellReferences.SpannedRangesCollection.Remove(range.Value); }
/// <summary> /// Force a cell to redraw. /// </summary> /// <param name="position"></param> public virtual void InvalidateCell(Position position) { InvalidateRange(new Range(position)); }
/// <summary> /// This method converts a Position to the real range of the cell. This is usefull when RowSpan or ColumnSpan is greater than 1. /// </summary> /// <returns></returns> public override Range RangeToCellRange(Range range) { int x = range.Start.Column; int x1 = range.End.Column; int y = range.Start.Row; int y1 = range.End.Row; for (int x2 = range.Start.Column; x2 <= range.End.Column; x2++) { for (int y2 = range.Start.Row; y2 <= range.End.Row; y2++) { var p = new Position(y2, x2); Range range2 = PositionToCellRange(p); if (range2.IsEmpty()) range2 = new Range(p, p); if (range2.Start.Column < x) x = range2.Start.Column; if (range2.End.Column > x1) x1 = range2.End.Column; if (range2.Start.Row < y) y = range2.Start.Row; if (range2.End.Row > y1) y1 = range2.End.Row; } } return new Range(y, x, y1, x1); }
/// <summary> /// This method converts a Position to the real start position of 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 and if you call this method with 0,1 return again 0,0. /// Get the real position for the specified position. For example when p_Position is a merged cell this method returns the starting position of the merged cells. /// Usually this method returns the same cell specified as parameter. This method is used for processing arrow keys, to find a valid cell when the focus is in a merged cell. /// For this class returns always p_Position. /// </summary> /// <param name="p_Position"></param> /// <returns></returns> public Position PositionToStartPosition(Position p_Position) { return PositionToCellRange(p_Position).Start; }
/// <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 void StartEdit(SourceGrid.Position Position) { SourceGrid.CellContext _Context = new SourceGrid.CellContext(grid1, Position, grid1[Position.Row, Position.Column]); _Context.StartEdit( ); }