/// <summary> /// Initializes a new instance of the <see cref="SortRangeRowsEventArgs"/> class. /// </summary> /// <param name="range">The range.</param> /// <param name="absoluteColumnIds">The absolute column keys.</param> /// <param name="isAscending">if set to <c>true</c> sort order is ascending.</param> /// <param name="cellComparer">The cell comparer.</param> public SortRangeRowsEventArgs(Range range, int absoluteColumnIds, bool isAscending, IComparer cellComparer) { this.range = range; this.absoluteColumnIds = absoluteColumnIds; this.isAscending = isAscending; this.cellComparer = cellComparer; }
/// <summary> /// Force a range of cells to redraw. If Redraw is set to false this function has no effects /// </summary> /// <param name="p_Range">The range.</param> public void InvalidateRange(Range p_Range) { p_Range = Range.Intersect(p_Range, CompleteRange); // to ensure the range is valid if (Redraw && p_Range.IsEmpty() == false)// && !this.DrawColLine) { Rectangle l_GridRectangle = RangeToDisplayRect(p_Range); Invalidate(l_GridRectangle, true); } }
/// <summary> /// Determines whether the ranges are equal. /// </summary> /// <param name="p_Range">The range.</param> /// <returns></returns> public bool Equals(Range p_Range) { return Start.Equals(p_Range.Start) && End.Equals(p_Range.End); }
/// <summary> /// Returns a range with the smaller Start and the bigger End, the Union of the two ranges. /// If one of the range is empty then returns other range. /// </summary> /// <param name="p_Range1">The range1.</param> /// <param name="p_Range2">The range2.</param> /// <returns></returns> public static Range Union(Range p_Range1, Range p_Range2) { if (p_Range1.IsEmpty()) { return p_Range2; } else if (p_Range2.IsEmpty()) { return p_Range1; } return new Range(Position.MergeMinor(p_Range1.Start, p_Range2.Start), Position.MergeMajor(p_Range1.End, p_Range2.End), false); }
/// <summary> /// Fired when calling SortRangeRows method /// </summary> /// <param name="e">The <see cref="Fr.Medit.MedDataGrid.SortRangeRowsEventArgs"/> instance containing the event data.</param> /// <remarks> /// This could be optimised by removing the duplicated sorting. /// </remarks> protected override void OnSortingRangeRows(SortRangeRowsEventArgs e) { base.OnSortingRangeRows(e); if (CustomSort == false && EnableSort == true) { if (e.AbsoluteColumnIndexes > e.Range.End.Column && e.AbsoluteColumnIndexes < e.Range.Start.Column) { throw new ArgumentOutOfRangeException("e", "Invalid e.AbsoluteColKeys"); } Range range = e.Range; if (this.FixedRows > 1 && this.FixedRows > e.Range.Start.Row) { range = new Range(this.FixedRows - e.Range.Start.Row + 1, e.Range.Start.Column, e.Range.End.Row, e.Range.End.Column); } ICell[][] sortableRange = new ICell[range.End.Row - range.Start.Row + 1][]; ICell[] cellsKeys = new ICell[range.End.Row - range.Start.Row + 1]; ICell[] selectCellsKeys = new ICell[range.End.Row - range.Start.Row + 1]; bool[][] sortableSelection = new bool[range.End.Row - range.Start.Row + 1][]; List<Range> selectionRange = new List<Range>(); int sortableRow = 0; for (int row = range.Start.Row; row <= range.End.Row; row++) { int sortableColumn = 0; sortableRange[sortableRow] = new ICell[range.End.Column - range.Start.Column + 1]; cellsKeys[sortableRow] = this[row, e.AbsoluteColumnIndexes]; selectCellsKeys[sortableRow] = this[row, e.AbsoluteColumnIndexes]; sortableSelection[sortableRow] = new bool[range.End.Column - range.Start.Column + 1]; for (int column = range.Start.Column; column <= range.End.Column; column++) { sortableRange[sortableRow][sortableColumn] = this[row, column]; if (this.doKeepSelection == true && this[row, column] != null) { sortableSelection[sortableRow][sortableColumn] = this[row, column].Select; } sortableColumn++; } sortableRow++; } IComparer cellComparer = e.CellComparer; if (cellComparer == null) { cellComparer = new ValueCellComparer(); } // SAA TODO: This is inefficient - we don't want 2 identical sorts! Array.Sort(cellsKeys, sortableRange, cellComparer); if (this.doKeepSelection == true) { Array.Sort(selectCellsKeys, sortableSelection, cellComparer); } // Apply sort sortableRow = 0; for (int i = 0; i <= range.End.Row - range.Start.Row; i++) { int row; if (e.Ascending) { row = range.Start.Row + i; } else { row = range.End.Row - i; } int sortableColumn = 0; for (int column = range.Start.Column; column <= range.End.Column; column++) { ICell sortedCell = sortableRange[sortableRow][sortableColumn]; if (sortedCell != null && sortedCell.Grid != null && sortedCell.Range.Start.Row >= 0 && sortedCell.Range.Start.Column >= 0) { RemoveCell(sortedCell.Range.Start.Row, sortedCell.Range.Start.Column); } this[row, column] = sortedCell; sortableColumn++; } if (this.doKeepSelection == true && sortableSelection[sortableRow][1] == true) { Range ra = new Range(new Position(row, 0), new Position(row, range.End.Column)); selectionRange.Add(ra); } sortableRow++; } if (this.doKeepSelection == true) { // and now we restore the selection in the grid foreach (Range selectedRange in selectionRange) { Selection.AddRange(selectedRange); } } } this.OnSortedRangeRows(e); }
/// <summary> /// Returns the absolute rectangle relative to the total scrollable area of the specified Range. Returns a 0 rectangle if the Range is not valid /// </summary> /// <param name="p_Range">The range.</param> /// <returns></returns> public override Rectangle RangeToAbsoluteRect(Range p_Range) { if (EnableRowColSpan) { // cerco il range anche tra le celle in rowspan o colspan Range l_RealRange = p_Range; for (int r = p_Range.Start.Row; r <= p_Range.End.Row; r++) { for (int c = p_Range.Start.Column; c <= p_Range.End.Column; c++) { ICell l_Cell = this[r, c]; if (l_Cell != null && (l_Cell.RowSpan > 1 || l_Cell.ColumnSpan > 1)) { l_RealRange = Range.Union(l_RealRange, l_Cell.Range); } } } return base.RangeToAbsoluteRect(l_RealRange); } else { return base.RangeToAbsoluteRect(p_Range); } }
private Range AddRangeCell(Range l_RangeToSelect) { bool isFound = false; if (l_RangeToSelect.Start == l_RangeToSelect.End && !Contains(l_RangeToSelect.Start)) { rangeList.Add(l_RangeToSelect); isFound = true; } // here we check whether the l_RangeToSelect is a subset of a row else if (l_RangeToSelect.Start.Row == l_RangeToSelect.End.Row) { int row = l_RangeToSelect.Start.Row; for (int col = l_RangeToSelect.Start.Column; col <= l_RangeToSelect.End.Column; ++col) { Position position = new Position(row, col); if (!Contains(position)) { rangeList.Add(new Range(position)); isFound = true; } } } // here we check whether the l_RangeToSelect is a subset of a column else if (l_RangeToSelect.Start.Column == l_RangeToSelect.End.Column) { int col = l_RangeToSelect.Start.Column; for (int row = l_RangeToSelect.Start.Row; row <= l_RangeToSelect.End.Row; ++row) { Position position = new Position(row, col); if (!Contains(position)) { rangeList.Add(new Range(position)); isFound = true; } } } else // This is a rectangle. { for (int row = l_RangeToSelect.Start.Row; row <= l_RangeToSelect.End.Row; ++row) { for (int col = l_RangeToSelect.Start.Column; col <= l_RangeToSelect.End.Column; ++col) { Position position = new Position(row, col); if (!Contains(position)) { rangeList.Add(new Range(position)); isFound = true; } } } } if (isFound) { OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Add, l_RangeToSelect)); } return l_RangeToSelect; }
/// <summary> /// Indicates whether the specified range of cells is selected. /// </summary> /// <param name="range">The range.</param> /// <returns> /// <c>true</c> if the selection contains the specified range; otherwise, <c>false</c>. /// </returns> public bool Contains(Range range) { if (Count <= 0) { return false; } // prima cerco se è presente un range esattamente come quello richiesto if (rangeList.Contains(range)) { return true; } // se non ho trovato uguale provo a cercare cella per cella IList<Position> l_SearchList = range.GetCellsPositions(); for (int i = 0; i < l_SearchList.Count; i++) { bool isFound = false; for (int r = 0; r < Count; r++) { if (this[r].Contains(l_SearchList[i])) { isFound = true; break; } } if (isFound == false) { return false; } } return true; }
/// <summary> /// Fired when the selection with the mouse is finished /// </summary> /// <param name="e">The <see cref="Fr.Medit.MedDataGrid.RangeEventArgs"/> instance containing the event data.</param> protected virtual void OnMouseSelectionFinish(RangeEventArgs e) { oldMouseSelectionRange = Range.Empty; }
/// <summary> /// Fired when the mouse selection change /// </summary> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> protected virtual void OnMouseSelectionChange(EventArgs e) { Range l_MouseRange = MouseSelectionRange; OnUndoMouseSelection(new RangeEventArgs(oldMouseSelectionRange)); OnApplyMouseSelection(new RangeEventArgs(l_MouseRange)); oldMouseSelectionRange = l_MouseRange; }
/// <summary> /// Fired when the mouse selection finish /// </summary> protected void MouseSelectionFinish() { if (mouseSelectionRange != Range.Empty) { OnMouseSelectionFinish(new RangeEventArgs(oldMouseSelectionRange)); } mouseSelectionRange = Range.Empty; }
/// <summary> /// Fired when the corner of the mouse selection change. For internal use only. /// </summary> /// <param name="p_Corner">The corner.</param> protected virtual void ChangeMouseSelectionCorner(Position p_Corner) { bool isChanged = false; if (mouseSelectionRange.Start != focusPosition || mouseSelectionRange.End != p_Corner) { isChanged = true; } mouseSelectionRange = new Range(focusPosition, p_Corner); if (isChanged) { OnMouseSelectionChange(EventArgs.Empty); OnUserSelection(new UserSelectionEventArgs(selection)); } }
/// <summary> /// Sort a range of the grid. /// </summary> /// <param name="p_Range">The range.</param> /// <param name="p_AbsoluteColKeys">Index of the column relative to the grid to use as sort keys, must be between start and end col</param> /// <param name="p_bAscending">Ascending true, Descending false</param> /// <param name="p_CellComparer">CellComparer, if null the default ValueCellComparer comparer will be used</param> public void SortRangeRows(Range p_Range, int p_AbsoluteColKeys, bool p_bAscending, IComparer p_CellComparer) { this.Cursor = Cursors.WaitCursor; bool l_oldRedraw = Redraw; Redraw = false; isSorting = true; try { SortRangeRowsEventArgs eventArgs = new SortRangeRowsEventArgs(p_Range, p_AbsoluteColKeys, p_bAscending, p_CellComparer); OnSortingRangeRows(eventArgs); OnSortedRangeRows(eventArgs); } finally { Redraw = l_oldRedraw; isSorting = false; } this.Cursor = Cursors.Arrow; }
/// <summary> /// Returns the relative rectangle to the current scrollable area of the specified Range. Returns a 0 rectangle if the Range is not valid /// </summary> /// <param name="p_Range">The range.</param> /// <returns></returns> public Rectangle RangeToDisplayRect(Range p_Range) { if (p_Range.IsEmpty()) { return new Rectangle(0, 0, 0, 0); } Rectangle l_Absolute = RangeToAbsoluteRect(p_Range); Rectangle l_Display = RectangleAbsoluteToRelative(l_Absolute); CellPositionType l_Type = GetPositionType(p_Range.Start); if (l_Type == CellPositionType.FixedTopLeft) { return new Rectangle(l_Absolute.X, l_Absolute.Y, l_Absolute.Width, l_Absolute.Height); } else if (l_Type == CellPositionType.FixedTop) { return new Rectangle(l_Display.X, l_Absolute.Y, l_Absolute.Width, l_Absolute.Height); } else if (l_Type == CellPositionType.FixedLeft) { return new Rectangle(l_Absolute.X, l_Display.Y, l_Absolute.Width, l_Absolute.Height); } else if (l_Type == CellPositionType.Scrollable) { return l_Display; } else { return new Rectangle(0, 0, 0, 0); } }
/// <summary> /// Returns the absolute rectangle relative to the total scrollable area of the specified Range. Returns a 0 rectangle if the Range is not valid /// </summary> /// <param name="p_Range">The range.</param> /// <returns></returns> public virtual Rectangle RangeToAbsoluteRect(Range p_Range) { if (p_Range.IsEmpty()) { return new Rectangle(0, 0, 0, 0); } int l_Left = Columns[p_Range.Start.Column].Left; int l_Top = Rows[p_Range.Start.Row].Top; return new Rectangle(l_Left, // x l_Top, // y Columns[p_Range.End.Column].Right - l_Left, // width Rows[p_Range.End.Row].Bottom - l_Top); // height }
private void RemoveRangeRow(Range p_Range) { Range l_RangeToDeselect = p_Range; if (this.grid.ColumnsCount > 0) { l_RangeToDeselect = new Range(p_Range.Start.Row, 0, p_Range.End.Row, grid.ColumnsCount - 1); } // optimisation pour les selections en ligne // algo : regarder si le Range correspond a une ligne entiere // si oui on applique l'aglo de decoupage de m_RangeList int startColumnGrid = 0; // the first column to select: it is 0 if the first column is not a header cell. if (this.grid.RowsCount > 1 && this.grid.ColumnsCount > 0 && this.grid.GetCell(1, 0) is Cells.Real.HeaderCell) { startColumnGrid = 1; } else if (this.grid.RowsCount == 1 && this.grid.ColumnsCount > 0 && this.grid.GetCell(0, 0) is Cells.Real.HeaderCell) { startColumnGrid = 1; } List<Range> l_rangesToAdd = new List<Range>(); bool selectionChanged = false; foreach (Range l_range in rangeList) { if (l_range.Start.Row == l_range.End.Row && l_range.Start.Row == l_RangeToDeselect.Start.Row && l_range.Start.Row == l_RangeToDeselect.End.Row) { selectionChanged = true; } // SL<SP && SP<EL && EL<EP else if (l_range.Start.Row < l_RangeToDeselect.Start.Row && l_RangeToDeselect.Start.Row < l_range.End.Row && l_range.End.Row < l_RangeToDeselect.End.Row) { selectionChanged = true; l_rangesToAdd.Add(new Range(l_range.Start.Row, startColumnGrid, l_RangeToDeselect.Start.Row - 1, grid.ColumnsCount - 1)); } // SP<SL && SL<EP && EP<EL else if (l_RangeToDeselect.Start.Row < l_range.Start.Row && l_range.Start.Row < l_RangeToDeselect.End.Row && l_RangeToDeselect.End.Row < l_range.End.Row) { selectionChanged = true; l_rangesToAdd.Add(new Range(l_RangeToDeselect.End.Row + 1, startColumnGrid, l_range.End.Row, grid.ColumnsCount - 1)); } // SL<SP && EP<EL else if (l_range.Start.Row < l_RangeToDeselect.Start.Row && l_RangeToDeselect.End.Row < l_range.End.Row) { selectionChanged = true; l_rangesToAdd.Add(new Range(l_range.Start.Row, startColumnGrid, l_RangeToDeselect.Start.Row - 1, grid.ColumnsCount - 1)); l_rangesToAdd.Add(new Range(l_RangeToDeselect.End.Row + 1, startColumnGrid, l_range.End.Row, grid.ColumnsCount - 1)); } else if (l_range.Start.Row == l_RangeToDeselect.Start.Row) { selectionChanged = true; if (l_RangeToDeselect.End.Row < l_range.End.Row) { l_rangesToAdd.Add(new Range(l_RangeToDeselect.End.Row + 1, startColumnGrid, l_range.End.Row, grid.ColumnsCount - 1)); } } else if (l_range.End.Row == l_RangeToDeselect.End.Row) { selectionChanged = true; if (l_range.Start.Row < l_RangeToDeselect.Start.Row) { l_rangesToAdd.Add(new Range(l_range.Start.Row, startColumnGrid, l_RangeToDeselect.Start.Row - 1, grid.ColumnsCount - 1)); } } else if (!(l_RangeToDeselect.Start.Row < l_range.Start.Row && l_range.End.Row < l_RangeToDeselect.End.Row)) { l_rangesToAdd.Add(l_range); } } rangeList.Clear(); foreach (Range range in l_rangesToAdd) { rangeList.Add(range); } if (selectionChanged) { OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Remove, l_RangeToDeselect)); } }
/// <summary> /// Select the specified Range of cells /// </summary> /// <param name="p_Range">The range.</param> public void AddRange(Range p_Range) { if (p_Range.IsEmpty() == true || grid.ColumnsCount == 0 || grid.RowsCount == 0) { return; } Range l_RangeToSelect = p_Range; // Apply SelectionMode if (selectionMode == GridSelectionMode.Row) { AddRangeRow(l_RangeToSelect); } else if (selectionMode == GridSelectionMode.Column) { AddRangeColumn(l_RangeToSelect); } else // if (selectionMode == GridSelectionMode.Cell) { l_RangeToSelect = AddRangeCell(l_RangeToSelect); } }
/// <summary> /// Draw a range of cells in the specified panel /// </summary> /// <param name="p_Panel">The panel.</param> /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param> /// <param name="p_Range">The range.</param> protected virtual void PaintRange(GridSubPanel p_Panel, PaintEventArgs e, Range p_Range) { Rectangle l_DrawRect; l_DrawRect = p_Panel.RectangleGridToPanel(PositionToDisplayRect(p_Range.Start)); Rectangle l_AbsRect = PositionToAbsoluteRect(p_Range.Start); int l_DeltaX = l_AbsRect.Left - l_DrawRect.Left; int l_DeltaY = l_AbsRect.Top - l_DrawRect.Top; Position l_p; for (int r = p_Range.Start.Row; r <= p_Range.End.Row; ++r) { int l_Top = Rows[r].Top - l_DeltaY; int l_Height = Rows[r].Height; for (int c = p_Range.Start.Column; c <= p_Range.End.Column; ++c) { l_DrawRect.Location = new Point(Columns[c].Left - l_DeltaX, l_Top); l_DrawRect.Size = new Size(Columns[c].Width, l_Height); ICellVirtual l_Cell = GetCell(r, c); if (l_Cell != null) { l_p = new Position(r, c); if (IsCellVisible(l_p)) { PaintCell(p_Panel, e, l_Cell, l_p, l_DrawRect); } else { while (c != p_Range.End.Column && !IsCellVisible(l_p)) { c++; l_p = new Position(r, c); } } } } } }
/// <summary> /// Deselect and remove from the collection the specified range of cells /// </summary> /// <param name="range">The range.</param> /// <remarks> /// if GridSelectionMode is Cell this method work only if we have 1 cell in the range /// </remarks> public void RemoveRange(Range range) { if (range.IsEmpty() == true) { return; } if (selectionMode == GridSelectionMode.Row) { RemoveRangeRow(range); } else if (selectionMode == GridSelectionMode.Column) { RemoveRangeColumn(range); } else // GridSelectionMode.Cell { RemoveRangeCell(range); } }
private void rows_RowsRemoved(object sender, IndexRangeEventArgs e) { Range l_RemovedRange = new Range(e.StartIndex, 0, e.StartIndex + e.Count - 1, ColumnsCount - 1); if (l_RemovedRange.Contains(FocusCellPosition)) { SetFocusCell(Position.Empty); } if (l_RemovedRange.Contains(mouseCellPosition)) { mouseCellPosition = Position.Empty; } if (l_RemovedRange.Contains(mouseDownPosition)) { mouseDownPosition = Position.Empty; } }
/// <summary> /// Initializes a new instance of the <see cref="SelectionChangedEventArgs"/> class. /// </summary> /// <param name="eventType">Type of the event.</param> /// <param name="range">The range.</param> public SelectionChangedEventArgs(SelectionChangedEventType eventType, Range range) { this.eventType = eventType; this.range = range; }
/// <summary> /// Initializes a new instance of the <see cref="RangeEventArgs"/> class. /// </summary> /// <param name="range">The grid range.</param> public RangeEventArgs(Range range) { this.range = range; }
/// <summary> /// Removes the rows specified by the range. /// </summary> /// <remarks> /// SAA TODO: Tidy and shorten this ugly method. /// </remarks> /// <param name="p_gridRange">The grid range.</param> public virtual void RemoveRangeRows(IList<Range> p_gridRange) { Range range; int count; int start; int removedRowsCount = 0; Range next_range_to_remove; int next_start = 0; bool deleteRows = false; int r, c; IEnumerator myEnum = p_gridRange.GetEnumerator(); List<Range> l_RangesToDelete = new List<Range>(); int[] l_RangeKeys = new int[p_gridRange.Count]; // tableau pour trier les Range Range[] l_RangeItems = new Range[p_gridRange.Count]; // avant tout il faut ordonner les range avec Start count = 0; while (myEnum.MoveNext()) { l_RangeKeys[count] = ((Range)myEnum.Current).Start.Row; // trie suivant les valeurs de Start l_RangeItems[count] = (Range)myEnum.Current; ++count; } // trie du tableau Array.Sort(l_RangeKeys, l_RangeItems); // on remplace les donne de p_gridRange par celle du tableau de Range trie p_gridRange.Clear(); myEnum = l_RangeItems.GetEnumerator(); while (myEnum.MoveNext()) { l_RangesToDelete.Add((Range)myEnum.Current); } myEnum = l_RangesToDelete.GetEnumerator(); IEnumerator myEnum_2 = l_RangesToDelete.GetEnumerator(); myEnum_2.MoveNext(); while (myEnum.MoveNext()) { range = (Range)myEnum.Current; count = range.End.Row - range.Start.Row + 1; if (count < 0 || count == 0) { count = 1; } // move to unselected cells if (range.End.Row == RowsCount - 1) { start = range.Start.Row; deleteRows = true; } else { start = range.Start.Row + count; deleteRows = false; } // myEnum_2 = myEnum; while ((Range)myEnum_2.Current != (Range)myEnum.Current) { myEnum_2.MoveNext(); } if (myEnum_2.MoveNext()) { next_range_to_remove = (Range)myEnum_2.Current; bool fbln = true; if (start >= next_range_to_remove.Start.Row) { int nb_range_ignore = 0; // si start du range courant est au dessus du start du range suivant while (start >= next_range_to_remove.Start.Row) { start = next_range_to_remove.End.Row + 1; count += next_range_to_remove.End.Row - next_range_to_remove.Start.Row + 1; ++nb_range_ignore; fbln = myEnum_2.MoveNext(); if (next_range_to_remove.End.Row == next_range_to_remove.Start.Row && next_range_to_remove.End.Row > start && fbln) { --count; } if (!fbln) // si false : il n'y a plus de range dans le tableau { next_start = RowsCount - 1; break; } next_range_to_remove = (Range)myEnum_2.Current; } while (nb_range_ignore > 0) { myEnum.MoveNext(); --nb_range_ignore; } } else { next_range_to_remove = (Range)myEnum_2.Current; // next_start = next_range_to_remove.Start.Row-1; } if (fbln) { next_start = next_range_to_remove.Start.Row - 1; if (next_start < range.End.Row) { next_start = range.Start.Row + count - 1; } } } else { next_start = RowsCount - 1; } myEnum_2.Reset(); myEnum_2.MoveNext(); removedRowsCount += count; if (deleteRows == false) { for (r = start; r <= next_start; r++) { for (c = 0; c < ColumnsCount; c++) { Cells.ICell tmp = this[r, c]; RemoveCell(r, c); InsertCell(r - removedRowsCount, c, tmp); } } } else { for (r = start; r < next_start; r++) { for (c = 0; c < ColumnsCount; c++) { RemoveCell(r, c); } } break; } } Redimension(RowsCount - removedRowsCount, ColumnsCount); }
private void AddRangeColumn(Range l_RangeToSelect) { if (this.grid.SelectColumnHeader && this.grid.FixedRows > 0 && this.grid.Rows[0].Height > 0) { l_RangeToSelect = new Range(0, l_RangeToSelect.Start.Column, this.grid.RowsCount - 1, l_RangeToSelect.End.Column); } else { l_RangeToSelect = new Range(this.grid.FixedRows, l_RangeToSelect.Start.Column, this.grid.RowsCount - 1, l_RangeToSelect.End.Column); } List<Range> l_rangesToAdd = new List<Range>(); if (rangeList.Count > 0) { bool isAdded = false; foreach (Range l_range in rangeList) { // SL<SP && SP<EL && EL<EP if (l_range.Start.Column < l_RangeToSelect.Start.Column && l_RangeToSelect.Start.Column < l_range.End.Column && l_range.End.Column < l_RangeToSelect.End.Column) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_range.Start.Column, grid.RowsCount - 1, l_RangeToSelect.End.Column)); } // SP<SL && SL<EP && EP<EL else if (l_RangeToSelect.Start.Column < l_range.Start.Column && l_range.Start.Column < l_RangeToSelect.End.Column && l_RangeToSelect.End.Column < l_range.End.Column) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, grid.RowsCount - 1, l_range.End.Column)); } else if (l_range.Start.Column == l_RangeToSelect.Start.Column) { if (l_range.End.Column < l_RangeToSelect.End.Column) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_range.Start.Column, grid.RowsCount - 1, l_RangeToSelect.End.Column)); } else { continue; } } else if (l_range.End.Column == l_RangeToSelect.End.Column) { if (l_RangeToSelect.Start.Column < l_range.Start.Column) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, grid.RowsCount - 1, l_RangeToSelect.End.Column)); } else { continue; } } else if (l_RangeToSelect.Start.Column < l_range.Start.Column && l_range.End.Column < l_RangeToSelect.End.Column) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, grid.RowsCount - 1, l_RangeToSelect.End.Column)); } else { // l_rangesToAdd.Add(l_range); if (!isAdded) { if (Contains(l_RangeToSelect) == false) { l_rangesToAdd.Add(l_RangeToSelect); isAdded = true; } } } } foreach (Range range in l_rangesToAdd) { rangeList.Add(range); } } else { rangeList.Add(l_RangeToSelect); } OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Add, l_RangeToSelect)); }
/// <summary> /// Returns the intersection between the two ranges. /// If one of the range is empty then the return is empty. /// </summary> /// <param name="p_Range1">The range1.</param> /// <param name="p_Range2">The range2.</param> /// <returns></returns> public static Range Intersect(Range p_Range1, Range p_Range2) { if (p_Range1.IsEmpty() || p_Range2.IsEmpty()) { return Range.Empty; } return new Range(Position.MergeMinor(p_Range1.Start, p_Range2.Start), Position.MergeMinor(p_Range1.End, p_Range2.End), false); }
private void AddRangeRow(Range l_RangeToSelect) { if (this.grid.SelectRowHeader && grid.FixedColumns > 0 && grid.Columns[0].Width > 0) { l_RangeToSelect = new Range(l_RangeToSelect.Start.Row, this.grid.FixedColumns, l_RangeToSelect.End.Row, this.grid.ColumnsCount - 1); } else { // Special case a lot faster l_RangeToSelect = new Range(l_RangeToSelect.Start.Row, 0, l_RangeToSelect.End.Row, grid.ColumnsCount - 1); rangeList.Add(l_RangeToSelect); OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Add, l_RangeToSelect)); return; } List<Range> l_rangesToAdd = new List<Range>(); if (rangeList.Count > 0) { bool isAdded = false; foreach (Range l_range in rangeList) { // SL<SP && SP<EL && EL<EP if (l_range.Start.Row < l_RangeToSelect.Start.Row && l_RangeToSelect.Start.Row < l_range.End.Row && l_range.End.Row < l_RangeToSelect.End.Row) { l_rangesToAdd.Add(new Range(l_range.Start.Row, l_RangeToSelect.Start.Column, l_RangeToSelect.End.Row, grid.ColumnsCount - 1)); } // SP<SL && SL<EP && EP<EL else if (l_RangeToSelect.Start.Row < l_range.Start.Row && l_range.Start.Row < l_RangeToSelect.End.Row && l_RangeToSelect.End.Row < l_range.End.Row) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, l_range.End.Row, grid.ColumnsCount - 1)); } else if (l_range.Start.Row == l_RangeToSelect.Start.Row) { if (l_range.End.Row < l_RangeToSelect.End.Row) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, l_RangeToSelect.End.Row, grid.ColumnsCount - 1)); } else if (l_range.End.Row != l_RangeToSelect.End.Row) { continue; } else if (!isAdded) { if (Contains(l_RangeToSelect) == false) { l_rangesToAdd.Add(l_RangeToSelect); isAdded = true; } } } else if (l_range.End.Row == l_RangeToSelect.End.Row) { if (l_RangeToSelect.Start.Row < l_range.Start.Row) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, l_RangeToSelect.End.Row, grid.ColumnsCount - 1)); } else if (l_range.Start.Row != l_RangeToSelect.Start.Row) { continue; } else if (!isAdded) { if (Contains(l_RangeToSelect) == false) { l_rangesToAdd.Add(l_RangeToSelect); isAdded = true; } } } else if (l_RangeToSelect.Start.Row < l_range.Start.Row && l_range.End.Row < l_RangeToSelect.End.Row) { l_rangesToAdd.Add(new Range(l_RangeToSelect.Start.Row, l_RangeToSelect.Start.Column, l_RangeToSelect.End.Row, grid.ColumnsCount - 1)); } else { // l_rangesToAdd.Add(l_range); if (!isAdded) { if (Contains(l_RangeToSelect) == false) { l_rangesToAdd.Add(l_RangeToSelect); isAdded = true; } } } } foreach (Range range in l_rangesToAdd) { rangeList.Add(range); } } else { rangeList.Add(l_RangeToSelect); } OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Add, l_RangeToSelect)); }
/// <summary> /// Returns true if the specified range is present in the current range. /// </summary> /// <param name="p_Range">The range.</param> /// <returns></returns> public bool Contains(Range p_Range) { return Contains(p_Range.Start) && Contains(p_Range.End); }
private void RemoveRangeCell(Range l_RangeToDeselect) { bool selectionChanged = false; if (l_RangeToDeselect.Start == l_RangeToDeselect.End && Contains(l_RangeToDeselect.Start)) { rangeList.Remove(l_RangeToDeselect); selectionChanged = true; } // here we check whether the l_RangeToDeselect is a subset of a row else if (l_RangeToDeselect.Start.Row == l_RangeToDeselect.End.Row) { int row = l_RangeToDeselect.Start.Row; for (int col = l_RangeToDeselect.Start.Column; col <= l_RangeToDeselect.End.Column; ++col) { Position position = new Position(row, col); if (Contains(position)) { rangeList.Remove(new Range(position)); selectionChanged = true; } } } // here we check whether the l_RangeToDeselect is a subset of a column else if (l_RangeToDeselect.Start.Column == l_RangeToDeselect.End.Column) { int col = l_RangeToDeselect.Start.Column; for (int row = l_RangeToDeselect.Start.Row; row <= l_RangeToDeselect.End.Row; ++row) { Position position = new Position(row, col); if (Contains(position)) { rangeList.Remove(new Range(position)); selectionChanged = true; } } } if (selectionChanged) { OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Remove, l_RangeToDeselect)); } }
private void RemoveRangeColumn(Range p_Range) { Range l_RangeToDeselect = p_Range; if (this.grid.RowsCount > 0) { l_RangeToDeselect = new Range(0, p_Range.Start.Column, grid.RowsCount - 1, p_Range.End.Column); } // optimisation pour les selections en ligne // algo : regarder si le Range correspond a une ligne entiere // si oui on applique l'aglo de decoupage de m_RangeList int startRowGrid = 0; // the first row to select: it is 0 if the first row is not a column header if (this.grid.RowsCount > 0 && this.grid.ColumnsCount > 1 && this.grid.GetCell(0, 1) is Cells.Real.HeaderCell) { startRowGrid = 1; } else if (this.grid.RowsCount > 0 && this.grid.ColumnsCount == 1 && this.grid.GetCell(0, 0) is Cells.Real.HeaderCell) { startRowGrid = 1; } List<Range> l_rangesToAdd = new List<Range>(); bool selectionChanged = false; foreach (Range l_range in rangeList) { if (l_range.Start.Column == l_range.End.Column && l_range.Start.Column == l_RangeToDeselect.Start.Column && l_range.Start.Column == l_RangeToDeselect.End.Column) { selectionChanged = true; } else if (l_range.Start.Column < l_RangeToDeselect.Start.Column && l_RangeToDeselect.Start.Column < l_range.End.Column && l_range.End.Column < l_RangeToDeselect.End.Column) { selectionChanged = true; l_rangesToAdd.Add(new Range(startRowGrid, l_range.Start.Column, grid.RowsCount - 1, l_RangeToDeselect.Start.Column - 1)); } else if (l_RangeToDeselect.Start.Column < l_range.Start.Column && l_range.Start.Column < l_RangeToDeselect.End.Column && l_RangeToDeselect.End.Column < l_range.End.Column) { selectionChanged = true; l_rangesToAdd.Add(new Range(startRowGrid, l_RangeToDeselect.End.Column + 1, grid.RowsCount - 1, l_range.End.Column)); } else if (l_range.Start.Column < l_RangeToDeselect.Start.Column && l_RangeToDeselect.End.Column < l_range.End.Column) { selectionChanged = true; l_rangesToAdd.Add(new Range(startRowGrid, l_range.Start.Column, grid.RowsCount - 1, l_RangeToDeselect.End.Column - 1)); l_rangesToAdd.Add(new Range(startRowGrid, l_RangeToDeselect.End.Column + 1, grid.RowsCount - 1, l_range.End.Column)); } else if (l_range.Start.Column == l_RangeToDeselect.Start.Column) { selectionChanged = true; if (l_RangeToDeselect.End.Column < l_range.End.Column) { l_rangesToAdd.Add(new Range(startRowGrid, l_RangeToDeselect.End.Column + 1, grid.RowsCount - 1, l_range.End.Column)); } } else if (l_range.End.Column == l_RangeToDeselect.End.Column) { selectionChanged = true; if (l_range.Start.Column < l_RangeToDeselect.Start.Column) { l_rangesToAdd.Add(new Range(startRowGrid, l_range.Start.Column, grid.RowsCount - 1, l_RangeToDeselect.Start.Column - 1)); } } else if (!(l_RangeToDeselect.Start.Column < l_range.Start.Column && l_range.End.Column < l_RangeToDeselect.End.Column)) { l_rangesToAdd.Add(l_range); } } rangeList.Clear(); foreach (Range range in l_rangesToAdd) { rangeList.Add(range); } if (selectionChanged) { OnSelectionChange(new SelectionChangedEventArgs(SelectionChangedEventType.Remove, l_RangeToDeselect)); } }
/// <summary> /// Auto size all the columns and all the rows with the required width and height /// </summary> /// <param name="p_MinHeight">Minimum Height</param> /// <param name="p_MinWidth">Minimum Width</param> /// <param name="p_RangeToAutoSize">Range to autosize.</param> public virtual void AutoSizeRange(int p_MinHeight, int p_MinWidth, Range p_RangeToAutoSize) { if (p_RangeToAutoSize.IsEmpty() == false) { bool l_bOldRedraw = Redraw; bool l_bOldAutoCalculateTop = Rows.AutoCalculateTop; bool l_bOldAutoCalculateLeft = Columns.AutoCalculateLeft; try { Redraw = false; Rows.AutoCalculateTop = false; Columns.AutoCalculateLeft = false; for (int c = p_RangeToAutoSize.End.Column; c >= p_RangeToAutoSize.Start.Column; c--) { AutoSizeColumnRange(c, p_MinWidth, p_RangeToAutoSize.Start.Row, p_RangeToAutoSize.End.Row); } for (int r = p_RangeToAutoSize.End.Row; r >= p_RangeToAutoSize.Start.Row; r--) { AutoSizeRowRange(r, p_MinHeight, p_RangeToAutoSize.Start.Column, p_RangeToAutoSize.End.Column); } } finally { Rows.AutoCalculateTop = l_bOldAutoCalculateTop; Columns.AutoCalculateLeft = l_bOldAutoCalculateLeft; Redraw = l_bOldRedraw; } // questo codice deve essere fatto dopo AutoCalculateTop e AutoCalculateLeft if (AutoStretchColumnsToFitWidth) { StretchColumnsToFitWidth(); } if (AutoStretchRowsToFitHeight) { StretchRowsToFitHeight(); } } }