1042 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1042 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System.Collections.Generic;
 | |
| using System.Drawing;
 | |
| 
 | |
| namespace DevComponents.DotNetBar.SuperGrid
 | |
| {
 | |
|     internal class MergeScan
 | |
|     {
 | |
|         #region Private variables
 | |
| 
 | |
|         private GridContainer _GridContainer;
 | |
|         private GridPanel _GridPanel;
 | |
| 
 | |
|         private List<CellRange> _ScanItems;
 | |
|         private List<DisplayRange> _LastDrs;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region ScanItems
 | |
| 
 | |
|         ///<summary>
 | |
|         /// ScanItems
 | |
|         ///</summary>
 | |
|         public List<CellRange> ScanItems
 | |
|         {
 | |
|             get { return (GetScanItems()); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         ///<summary>
 | |
|         /// MergeScan
 | |
|         ///</summary>
 | |
|         ///<param name="gridContainer"></param>
 | |
|         public MergeScan(GridContainer gridContainer)
 | |
|         {
 | |
|             _GridContainer = gridContainer;
 | |
|             _GridPanel = _GridContainer.GridPanel;
 | |
|         }
 | |
| 
 | |
|         #region GetScanItems
 | |
| 
 | |
|         internal List<CellRange> GetScanItems()
 | |
|         {
 | |
|             if (_GridContainer != null && _GridPanel != null)
 | |
|             {
 | |
|                 int rowCount = GetRowCount();
 | |
| 
 | |
|                 if (rowCount > 0)
 | |
|                 {
 | |
|                     SuperGridControl sg = _GridPanel.SuperGrid;
 | |
| 
 | |
|                     if (sg.NeedMergeLayout == true)
 | |
|                         _GridContainer.NeedMergeLayout = true;
 | |
| 
 | |
|                     if (_GridContainer.NeedMergeLayout == true ||
 | |
|                         _GridContainer.DisplayedMergeLayoutCount != sg.DisplayedMergeLayoutCount)
 | |
|                     {
 | |
|                         _ScanItems = GetDisplayedScanItems();
 | |
| 
 | |
|                         _GridContainer.NeedMergeLayout = false;
 | |
|                         _GridContainer.DisplayedMergeLayoutCount = sg.DisplayedMergeLayoutCount;
 | |
| 
 | |
|                         sg.PostInternalMouseMove();
 | |
|                         sg.DeactivateNonModalEditor();
 | |
|                     }
 | |
| 
 | |
|                     return (_ScanItems);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #region GetRowCount
 | |
| 
 | |
|         private int GetRowCount()
 | |
|         {
 | |
|             if (_GridPanel.VirtualMode == true)
 | |
|                 return (_GridPanel.VirtualRowCount);
 | |
| 
 | |
|             return (_GridContainer.Rows.Count);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDisplayedScanItems
 | |
| 
 | |
|         private List<CellRange> GetDisplayedScanItems()
 | |
|         {
 | |
|             List<DisplayRange> drs = GetDisplayRanges();
 | |
| 
 | |
|             if (drs != null)
 | |
|             {
 | |
|                 _GridPanel.SuperGrid.DoGetDisplayRangesEvent(_GridContainer, ref drs);
 | |
| 
 | |
|                 if (drs != null && drs.Count > 0)
 | |
|                     return (GetCellRanges(drs));
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #region GetDisplayRanges
 | |
| 
 | |
|         private List<DisplayRange> GetDisplayRanges()
 | |
|         {
 | |
|             GridPanel panel = _GridContainer as GridPanel;
 | |
| 
 | |
|             int frCount = 0;
 | |
|             int fcCount = 0;
 | |
| 
 | |
|             if (panel != null)
 | |
|             {
 | |
|                 frCount = panel.FrozenRowCount;
 | |
| 
 | |
|                 GridColumn lastColumn = panel.Columns.GetLastVisibleFrozenColumn();
 | |
| 
 | |
|                 if (lastColumn != null)
 | |
|                     fcCount = panel.Columns.GetDisplayIndex(lastColumn) + 1;
 | |
|             }
 | |
| 
 | |
|             DisplayRange dr = new DisplayRange();
 | |
| 
 | |
|             if (GetRowRange(dr) > 1 | GetColumnRange(dr) > 1)
 | |
|             {
 | |
|                 List<DisplayRange> drs;
 | |
| 
 | |
|                 if (frCount == 0 && fcCount == 0)
 | |
|                 {
 | |
|                     drs = new List<DisplayRange>();
 | |
|                     drs.Add(dr);
 | |
|                 }
 | |
|                 else if (frCount != 0 && fcCount != 0)
 | |
|                 {
 | |
|                     drs = new List<DisplayRange>(4);
 | |
| 
 | |
|                     drs.Add(GetNewRange(dr, 0, frCount, 0, fcCount));
 | |
|                     drs.Add(GetNewRange(dr, 0, frCount, fcCount, dr.ColumnCount));
 | |
|                     drs.Add(GetNewRange(dr, frCount, dr.RowCount, 0, fcCount));
 | |
|                     drs.Add(GetNewRange(dr, frCount, dr.RowEnd, fcCount, dr.ColumnCount));
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     drs = new List<DisplayRange>(2);
 | |
| 
 | |
|                     if (frCount != 0)
 | |
|                     {
 | |
|                         int n = (dr.RowStart < frCount ? frCount : dr.RowStart);
 | |
| 
 | |
|                         drs.Add(GetNewRange(dr, 0, frCount, dr.ColumnStart, dr.ColumnCount));
 | |
|                         drs.Add(GetNewRange(dr, n, dr.RowCount, dr.ColumnStart, dr.ColumnCount));
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         int n = (dr.ColumnStart < fcCount ? fcCount : dr.ColumnStart);
 | |
| 
 | |
|                         drs.Add(GetNewRange(dr, dr.RowStart, dr.RowCount, 0, fcCount));
 | |
|                         drs.Add(GetNewRange(dr, dr.RowStart, dr.RowCount, n, dr.ColumnCount));
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 return (drs);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #region GetRowRange
 | |
| 
 | |
|         private int GetRowRange(DisplayRange dr)
 | |
|         {
 | |
|             int rowCount = GetRowCount();
 | |
| 
 | |
|             if (rowCount < 50)
 | |
|             {
 | |
|                 dr.RowStart = 0;
 | |
|                 dr.RowEnd = rowCount;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Rectangle t = _GridContainer.SuperGrid.ViewRect;
 | |
| 
 | |
|                 dr.RowEnd = _GridContainer.FirstOnScreenRowIndex;
 | |
|                 dr.RowStart = GetPreviousRowIndex(dr.RowEnd);
 | |
| 
 | |
|                 bool fpass = false;
 | |
| 
 | |
|                 for (int i = dr.RowStart; i < rowCount; i++)
 | |
|                 {
 | |
|                     GridContainer item = GetRow(i);
 | |
| 
 | |
|                     if (item != null && item.Visible == true)
 | |
|                     {
 | |
|                         Rectangle r = item.BoundsRelative;
 | |
| 
 | |
|                         if (item.IsVFrozen == false)
 | |
|                             r.Y -= _GridContainer.VScrollOffset;
 | |
| 
 | |
|                         if (r.Y > t.Bottom)
 | |
|                         {
 | |
|                             if (fpass == true)
 | |
|                                 break;
 | |
| 
 | |
|                             fpass = true;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     dr.RowEnd = i;
 | |
|                 }
 | |
| 
 | |
|                 dr.RowEnd = GetNextRowIndex(dr.RowEnd) + 1;
 | |
|             }
 | |
| 
 | |
|             return (dr.RowCount);
 | |
|         }
 | |
| 
 | |
|         #region GetPreviousRowIndex
 | |
| 
 | |
|         private int GetPreviousRowIndex(int index)
 | |
|         {
 | |
|             if ((uint)index < GetRowCount())
 | |
|             {
 | |
|                 for (int i = index - 1; i >= 0; i--)
 | |
|                 {
 | |
|                     GridContainer row = GetRow(i);
 | |
| 
 | |
|                     if (row != null && row.Visible == true)
 | |
|                         return (i);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (index);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetNextRowIndex
 | |
| 
 | |
|         private int GetNextRowIndex(int index)
 | |
|         {
 | |
|             int rowCount = GetRowCount();
 | |
| 
 | |
|             if ((uint)index < rowCount)
 | |
|             {
 | |
|                 for (int i = index + 1; i < rowCount; i++)
 | |
|                 {
 | |
|                     GridContainer row = GetRow(i);
 | |
| 
 | |
|                     if (row != null && row.Visible == true)
 | |
|                         return (i);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (index);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetColumnRange
 | |
| 
 | |
|         private int GetColumnRange(DisplayRange dr)
 | |
|         {
 | |
|             GridColumnCollection columns = _GridPanel.Columns;
 | |
|             int colCount = columns.Count;
 | |
| 
 | |
|             dr.ColumnStart = 0;
 | |
|             dr.ColumnCount = colCount;
 | |
| 
 | |
|             if (colCount > 10)
 | |
|             {
 | |
|                 int[] map = columns.DisplayIndexMap;
 | |
| 
 | |
|                 for (int i = 0; i < map.Length; i++)
 | |
|                 {
 | |
|                     int index = map[i];
 | |
|                     GridColumn column = columns[index];
 | |
| 
 | |
|                     if (column.Visible == true)
 | |
|                     {
 | |
|                         if (column.IsOnScreen == true && column.IsHFrozen == false)
 | |
|                             break;
 | |
| 
 | |
|                         dr.ColumnStart = i;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 dr.ColumnEnd = dr.ColumnStart;
 | |
| 
 | |
|                 for (int i = dr.ColumnStart + 1; i < map.Length; i++)
 | |
|                 {
 | |
|                     int index = map[i];
 | |
|                     GridColumn column = columns[index];
 | |
| 
 | |
|                     if (column.Visible == true)
 | |
|                     {
 | |
|                         dr.ColumnEnd = i;
 | |
| 
 | |
|                         if (column.IsOnScreen == false)
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 dr.ColumnEnd++;
 | |
|             }
 | |
| 
 | |
|             return (dr.ColumnCount);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetNewRange
 | |
| 
 | |
|         private DisplayRange GetNewRange(DisplayRange dr,
 | |
|             int rowStart, int rowCount, int columnStart, int columnCount)
 | |
|         {
 | |
|             DisplayRange ndr = new DisplayRange();
 | |
| 
 | |
|             ndr.RowStart = rowStart;
 | |
|             ndr.RowCount = rowCount;
 | |
| 
 | |
|             if (ndr.RowEnd > dr.RowEnd)
 | |
|                 ndr.RowEnd = dr.RowEnd;
 | |
| 
 | |
|             ndr.ColumnStart = columnStart;
 | |
|             ndr.ColumnCount = columnCount;
 | |
| 
 | |
|             if (ndr.ColumnEnd > dr.ColumnEnd)
 | |
|                 ndr.ColumnEnd = dr.ColumnEnd;
 | |
| 
 | |
|             return (ndr);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetCellRanges
 | |
| 
 | |
|         private List<CellRange> GetCellRanges(List<DisplayRange> drs)
 | |
|         {
 | |
|             List<CellRange> cellRanges = null;
 | |
| 
 | |
|             if (_GridPanel.SuperGrid.EditorActive == true || LastScanIsValid(drs) == true)
 | |
|             {
 | |
|                 cellRanges = _ScanItems;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 foreach (DisplayRange dr in drs)
 | |
|                 {
 | |
|                     List<CellRange> crs = UpdateMergeRange(dr);
 | |
| 
 | |
|                     if (crs != null)
 | |
|                     {
 | |
|                         if (cellRanges != null)
 | |
|                             cellRanges.InsertRange(0, crs);
 | |
|                         else
 | |
|                             cellRanges = crs;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 _LastDrs = drs;
 | |
|             }
 | |
|             
 | |
|             if (cellRanges != null)
 | |
|             {
 | |
|                 _GridContainer.SuperGrid.BoundsUpdateCount++;
 | |
| 
 | |
|                 foreach (CellRange cr in cellRanges)
 | |
|                     cr.BackBounds = GetDisplayBounds(cr);
 | |
| 
 | |
|                 _GridContainer.GridPanel.UpdateSelectionCount();
 | |
|             }
 | |
| 
 | |
|             return (cellRanges);
 | |
|         }
 | |
| 
 | |
|         #region LastScanIsValid
 | |
| 
 | |
|         private bool LastScanIsValid(List<DisplayRange> drs)
 | |
|         {
 | |
|             if (_GridContainer.NeedMergeLayout == false)
 | |
|             {
 | |
|                 if (_LastDrs != null)
 | |
|                 {
 | |
|                     if (drs.Count == _LastDrs.Count)
 | |
|                     {
 | |
|                         for (int i = 0; i < drs.Count; i++)
 | |
|                         {
 | |
|                             if (drs[i].IsRangeEqualTo(_LastDrs[i]) == false)
 | |
|                                 return (false);
 | |
|                         }
 | |
| 
 | |
|                         return (true);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (false);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateMergeRange
 | |
| 
 | |
|         private List<CellRange> UpdateMergeRange(DisplayRange dr)
 | |
|         {
 | |
|             UpdateMergeFlags(dr);
 | |
|             UpdateMergeCount(dr);
 | |
| 
 | |
|             List<CellRange> cellRanges = null;
 | |
| 
 | |
|             if (_GridContainer.SuperGrid.DoGetCellRangesEvent(_GridContainer, dr, ref cellRanges) == false)
 | |
|                 cellRanges = GetCellMergeRanges(dr);
 | |
| 
 | |
|             if (cellRanges != null)
 | |
|                 PostProcessCellRanges(cellRanges);
 | |
| 
 | |
|             _GridContainer.SuperGrid.DoUpdateCellDisplayRangesEvent(_GridContainer, dr, ref cellRanges);
 | |
| 
 | |
|             return (cellRanges);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateMergeFlags
 | |
| 
 | |
|         private void UpdateMergeFlags(DisplayRange dr)
 | |
|         {
 | |
|             GridRow lastRow = null;
 | |
| 
 | |
|             for (int i = dr.RowStart; i < dr.RowEnd; i++)
 | |
|             {
 | |
|                 GridContainer item = GetRow(i);
 | |
| 
 | |
|                 if (item != null && item.Visible == true)
 | |
|                 {
 | |
|                     GridRow row = item as GridRow;
 | |
| 
 | |
|                     if (row != null)
 | |
|                     {
 | |
|                         SetHMergeFlags(row, dr);
 | |
|                         SetVMergeFlags(row, lastRow, dr);
 | |
|                     }
 | |
| 
 | |
|                     lastRow = row;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region SetHMergeFlags
 | |
| 
 | |
|         private void SetHMergeFlags(GridRow row, DisplayRange dr)
 | |
|         {
 | |
|             GridPanel panel = _GridContainer.GridPanel;
 | |
|             GridColumnCollection columns = panel.Columns;
 | |
| 
 | |
|             int[] map = columns.DisplayIndexMap;
 | |
| 
 | |
|             GridCell lastCell = null;
 | |
| 
 | |
|             for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | |
|             {
 | |
|                 int index = map[i];
 | |
| 
 | |
|                 GridColumn column = columns[index];
 | |
| 
 | |
|                 if (column.Visible == true)
 | |
|                 {
 | |
|                     GridCell cell = row[index];
 | |
| 
 | |
|                     if (cell != null)
 | |
|                     {
 | |
|                         if (lastCell != null)
 | |
|                         {
 | |
|                             if (_GridContainer.SuperGrid.NeedMergeLayout == true ||
 | |
|                                 cell.MergeUpdateCount != _GridContainer.MergeUpdateCount ||
 | |
|                                 lastCell.MergeUpdateCount != _GridContainer.MergeUpdateCount)
 | |
|                             {
 | |
|                                 bool merged = false;
 | |
| 
 | |
|                                 if (CanHMergeCells(panel, column, lastCell.GridColumn))
 | |
|                                     merged = CanMergeValues(cell, lastCell);
 | |
| 
 | |
|                                 cell.MergedLeft = merged;
 | |
|                                 lastCell.MergedRight = merged;
 | |
|                             }
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             cell.MergedLeft = false;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     lastCell = cell;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region CanHMergeCells
 | |
| 
 | |
|         private bool CanHMergeCells(
 | |
|             GridPanel panel, GridColumn column1, GridColumn column2)
 | |
|         {
 | |
|             return (IsHCellMerge(panel, column1.CellMergeMode, CellMergeMode.HorizontalLeft) &&
 | |
|                     IsHCellMerge(panel, column2.CellMergeMode, CellMergeMode.HorizontalRight));
 | |
|         }
 | |
| 
 | |
|         #region IsHCellMerge
 | |
| 
 | |
|         private bool IsHCellMerge(GridPanel panel, CellMergeMode cMode, CellMergeMode tMode)
 | |
|         {
 | |
|             if (cMode == CellMergeMode.NotSet)
 | |
|                 cMode = panel.CellMergeMode;
 | |
| 
 | |
|             return ((cMode & tMode) == tMode);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CanVMergeCells
 | |
| 
 | |
|         private bool CanVMergeCells(GridPanel panel, GridColumn column)
 | |
|         {
 | |
|             return (IsVCellMerge(panel, column.CellMergeMode));
 | |
|         }
 | |
| 
 | |
|         #region IsVCellMerge
 | |
| 
 | |
|         private bool IsVCellMerge(GridPanel panel, CellMergeMode mode)
 | |
|         {
 | |
|             if (mode == CellMergeMode.NotSet)
 | |
|                 mode = panel.CellMergeMode;
 | |
| 
 | |
|             return ((mode & CellMergeMode.Vertical) == CellMergeMode.Vertical);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SetVMergeFlags
 | |
| 
 | |
|         private void SetVMergeFlags(GridRow row, GridRow lastRow, DisplayRange dr)
 | |
|         {
 | |
|             GridPanel panel = _GridContainer.GridPanel;
 | |
|             GridColumnCollection columns = panel.Columns;
 | |
| 
 | |
|             int[] map = columns.DisplayIndexMap;
 | |
| 
 | |
|             for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | |
|             {
 | |
|                 int index = map[i];
 | |
| 
 | |
|                 GridColumn column = columns[index];
 | |
| 
 | |
|                 if (column.Visible == true)
 | |
|                 {
 | |
|                     GridCell cell = row[index];
 | |
| 
 | |
|                     if (cell != null)
 | |
|                     {
 | |
|                         if (lastRow != null)
 | |
|                         {
 | |
|                             GridCell lastCell = lastRow[index];
 | |
| 
 | |
|                             if (lastRow.Rows.Count <= 0 || lastRow.Expanded == false)
 | |
|                             {
 | |
|                                 if (lastCell != null)
 | |
|                                 {
 | |
|                                     if (_GridContainer.SuperGrid.NeedMergeLayout == true ||
 | |
|                                         cell.MergeUpdateCount != _GridContainer.MergeUpdateCount ||
 | |
|                                         cell.MergeUpdateCount != row.MergeUpdateCount ||
 | |
|                                         lastCell.MergeUpdateCount != _GridContainer.MergeUpdateCount ||
 | |
|                                         lastCell.MergeUpdateCount != lastRow.MergeUpdateCount)
 | |
|                                     {
 | |
|                                         bool merged = false;
 | |
| 
 | |
|                                         if (CanVMergeCells(panel, column) == true)
 | |
|                                             merged = CanMergeValues(cell, lastCell);
 | |
| 
 | |
|                                         cell.MergedTop = merged;
 | |
|                                         lastCell.MergedBottom = merged;
 | |
|                                     }
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     cell.MergedTop = false;
 | |
|                                 }
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 if (lastCell != null)
 | |
|                                     lastCell.MergedBottom = false;
 | |
| 
 | |
|                                 cell.MergedTop = false;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CanMergeValues
 | |
| 
 | |
|         private bool CanMergeValues(GridCell cell1, GridCell cell2)
 | |
|         {
 | |
|             if (cell1.IsValueNull || cell2.IsValueNull)
 | |
|             {
 | |
|                 if (cell1.Value == cell2.Value)
 | |
|                     return (cell1.AllowNullMerge & cell2.AllowNullMerge);
 | |
| 
 | |
|                 return (false);
 | |
|             }
 | |
| 
 | |
|             string s1 = cell1.FormattedValue;
 | |
|             string s2 = cell2.FormattedValue;
 | |
| 
 | |
|             return (s1.Equals(s2));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateMergeCount
 | |
| 
 | |
|         private void UpdateMergeCount(DisplayRange dr)
 | |
|         {
 | |
|             GridPanel panel = _GridContainer.GridPanel;
 | |
|             GridColumnCollection columns = panel.Columns;
 | |
| 
 | |
|             int[] map = columns.DisplayIndexMap;
 | |
| 
 | |
|             for (int i = dr.RowStart; i < dr.RowEnd; i++)
 | |
|             {
 | |
|                 GridContainer item = GetRow(i);
 | |
| 
 | |
|                 if (item != null && item.Visible == true)
 | |
|                 {
 | |
|                     GridRow row = item as GridRow;
 | |
| 
 | |
|                     if (row != null)
 | |
|                     {
 | |
|                         row.MergeUpdateCount = _GridContainer.MergeUpdateCount;
 | |
| 
 | |
|                         for (int j = dr.ColumnStart; j < dr.ColumnEnd; j++)
 | |
|                         {
 | |
|                             int index = map[j];
 | |
| 
 | |
|                             GridCell cell = row[index];
 | |
| 
 | |
|                             if (cell != null)
 | |
|                                 cell.MergeUpdateCount = _GridContainer.MergeUpdateCount;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetCellMergeRanges
 | |
| 
 | |
|         private List<CellRange> GetCellMergeRanges(DisplayRange dr)
 | |
|         {
 | |
|             switch (_GridPanel.CellMergeOrder)
 | |
|             {
 | |
|                 case CellMergeOrder.HorizontalThenVertical:
 | |
|                     return (MergeHCells(dr));
 | |
| 
 | |
|                 default:
 | |
|                     return (MergeVCells(dr));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region MergeVCells
 | |
| 
 | |
|         private List<CellRange> MergeVCells(DisplayRange dr)
 | |
|         {
 | |
|             List<CellRange> cellRanges = new List<CellRange>();
 | |
| 
 | |
|             GridColumnCollection columns = _GridContainer.GridPanel.Columns;
 | |
|             int[] map = columns.DisplayIndexMap;
 | |
| 
 | |
|             for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | |
|             {
 | |
|                 int index = map[i];
 | |
|                 GridColumn column = columns[index];
 | |
| 
 | |
|                 if (column.Visible == true)
 | |
|                 {
 | |
|                     CellRange cr = null;
 | |
| 
 | |
|                     for (int j = dr.RowStart; j < dr.RowEnd; j++)
 | |
|                     {
 | |
|                         GridRow row = GetRow(j);
 | |
| 
 | |
|                         if (row != null && row.Visible == true && row.IsTempInsertRow == false)
 | |
|                         {
 | |
|                             GridCell cell = row.GetCell(index);
 | |
| 
 | |
|                             if (cell != null)
 | |
|                             {
 | |
|                                 if (cell.MergedTop == true)
 | |
|                                 {
 | |
|                                     if (cr == null)
 | |
|                                         cr = new CellRange(j, i);
 | |
|                                     else
 | |
|                                         cr.RowEnd = j + 1;
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     OutputVCellRange(cellRanges, cr, map);
 | |
| 
 | |
|                                     cr = new CellRange(j, i);
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     OutputVCellRange(cellRanges, cr, map);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (cellRanges);
 | |
|         }
 | |
| 
 | |
|         #region OutputVCellRange
 | |
| 
 | |
|         private void OutputVCellRange(
 | |
|             List<CellRange> cellRanges, CellRange cr, int[] map)
 | |
|         {
 | |
|             if (cr != null)
 | |
|             {
 | |
|                 for (int i = 0; i < cellRanges.Count; i++)
 | |
|                 {
 | |
|                     CellRange crn = cellRanges[i];
 | |
| 
 | |
|                     if (crn.ColumnEnd == cr.ColumnStart)
 | |
|                     {
 | |
|                         if (crn.RowStart == cr.RowStart && crn.RowEnd == cr.RowEnd)
 | |
|                         {
 | |
|                             GridRow row = GetRow(cr.RowStart);
 | |
| 
 | |
|                             if (row != null)
 | |
|                             {
 | |
|                                 if (row[map[crn.ColumnEnd - 1]].MergedRight == true)
 | |
|                                 {
 | |
|                                     crn.ColumnEnd = cr.ColumnEnd;
 | |
|                                     cr = null;
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     if (crn.RowStart == crn.RowEnd && crn.ColumnStart == crn.ColumnEnd)
 | |
|                                         cellRanges.RemoveAt(i);
 | |
|                                 }
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (cr != null)
 | |
|                     cellRanges.Add(cr);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MergeHCells
 | |
| 
 | |
|         private List<CellRange> MergeHCells(DisplayRange dr)
 | |
|         {
 | |
|             List<CellRange> cellRanges = new List<CellRange>();
 | |
| 
 | |
|             GridColumnCollection columns = _GridPanel.Columns;
 | |
|             int[] map = columns.DisplayIndexMap;
 | |
| 
 | |
|             for (int j = dr.RowStart; j < dr.RowEnd; j++)
 | |
|             {
 | |
|                 GridRow row = GetRow(j);
 | |
| 
 | |
|                 if (row != null && row.Visible == true && row.IsTempInsertRow == false)
 | |
|                 {
 | |
|                     CellRange cr = null;
 | |
| 
 | |
|                     for (int i = dr.ColumnStart; i < dr.ColumnEnd; i++)
 | |
|                     {
 | |
|                         int index = map[i];
 | |
| 
 | |
|                         GridColumn column = columns[index];
 | |
| 
 | |
|                         if (column.Visible == true)
 | |
|                         {
 | |
|                             GridCell cell = row[index];
 | |
| 
 | |
|                             if (cell != null)
 | |
|                             {
 | |
|                                 if (cell.MergedLeft == true)
 | |
|                                 {
 | |
|                                     if (cr == null)
 | |
|                                         cr = new CellRange(j, i);
 | |
|                                     else
 | |
|                                         cr.ColumnEnd = i + 1;
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     OutputHCellRange(cellRanges, cr, map);
 | |
| 
 | |
|                                     cr = new CellRange(j, i);
 | |
|                                 }
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     OutputHCellRange(cellRanges, cr, map);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (cellRanges);
 | |
|         }
 | |
| 
 | |
|         #region OutputHCellRange
 | |
| 
 | |
|         private void OutputHCellRange(
 | |
|             List<CellRange> cellRanges, CellRange cr, int[] map)
 | |
|         {
 | |
|             if (cr != null)
 | |
|             {
 | |
|                 for (int i = 0; i < cellRanges.Count; i++)
 | |
|                 {
 | |
|                     CellRange crn = cellRanges[i];
 | |
| 
 | |
|                     if (crn.RowEnd == cr.RowStart)
 | |
|                     {
 | |
|                         if (crn.ColumnStart == cr.ColumnStart && crn.ColumnEnd == cr.ColumnEnd)
 | |
|                         {
 | |
|                             GridRow row = GetRow(crn.RowEnd - 1);
 | |
| 
 | |
|                             if (row != null)
 | |
|                             {
 | |
|                                 if (row[map[crn.ColumnEnd - 1]].MergedBottom == true)
 | |
|                                 {
 | |
|                                     crn.RowEnd = cr.RowEnd;
 | |
|                                     cr = null;
 | |
|                                 }
 | |
|                                 else
 | |
|                                 {
 | |
|                                     if (crn.RowStart == crn.RowEnd && crn.ColumnStart == crn.ColumnEnd)
 | |
|                                         cellRanges.RemoveAt(i);
 | |
|                                 }
 | |
|                             }
 | |
|                             break;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (cr != null)
 | |
|                     cellRanges.Add(cr);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PostProcessCellRanges
 | |
| 
 | |
|         private void PostProcessCellRanges(List<CellRange> cellRanges)
 | |
|         {
 | |
|             if (cellRanges != null)
 | |
|             {
 | |
|                 for (int i = cellRanges.Count - 1; i >= 0; i--)
 | |
|                 {
 | |
|                     CellRange cr = cellRanges[i];
 | |
| 
 | |
|                     if (cr.ColumnCount <= 1 && cr.RowCount <= 1)
 | |
|                     {
 | |
|                         cellRanges.RemoveAt(i);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         if (cr.FormattedValue == null)
 | |
|                         {
 | |
|                             GridCell cell = GetRow(cr.RowStart)[_GridPanel.Columns.DisplayIndexMap[cr.ColumnStart]];
 | |
| 
 | |
|                             if (cell != null)
 | |
|                             {
 | |
|                                 string s = cell.FormattedValue;
 | |
| 
 | |
|                                 cell.SuperGrid.DoGetCellRangeFormattedValueEvent((GridContainer)cell.GridRow.Parent, cr, ref s);
 | |
| 
 | |
|                                 cr.FormattedValue = s;
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 cr.FormattedValue = "";
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetDisplayBounds
 | |
| 
 | |
|         private Rectangle GetDisplayBounds(CellRange cr)
 | |
|         {
 | |
|             Rectangle r = Rectangle.Empty;
 | |
| 
 | |
|             if (cr != null)
 | |
|             {
 | |
|                 GridPanel panel = _GridContainer.GridPanel;
 | |
|                 int[] map = panel.Columns.DisplayIndexMap;
 | |
| 
 | |
|                 int rowHeight = 200;
 | |
| 
 | |
|                 for (int ri = cr.RowStart; ri < cr.RowEnd; ri++)
 | |
|                 {
 | |
|                     GridRow row = GetRow(ri);
 | |
| 
 | |
|                     if (row.Visible == true)
 | |
|                     {
 | |
|                         for (int ci = cr.ColumnStart; ci < cr.ColumnEnd; ci++)
 | |
|                         {
 | |
|                             int index = map[ci];
 | |
| 
 | |
|                             GridCell cell = row.GetCell(index);
 | |
| 
 | |
|                             if (cell != null)
 | |
|                             {
 | |
|                                 r = (r.IsEmpty == true)
 | |
|                                         ? cell.BackBounds
 | |
|                                         : Rectangle.Union(r, cell.BackBounds);
 | |
|                             }
 | |
|                         }
 | |
| 
 | |
|                         if (rowHeight > row.FixedRowHeight)
 | |
|                             rowHeight = row.FixedRowHeight;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (r.IsEmpty == false)
 | |
|                     r = AdjustMergeRect(panel, map, r, cr, rowHeight);
 | |
|             }
 | |
| 
 | |
|             return (r);
 | |
|         }
 | |
| 
 | |
|         #region AdjustMergeRect
 | |
| 
 | |
|         private Rectangle AdjustMergeRect(GridPanel panel,
 | |
|             int[] map, Rectangle r, CellRange cr, int rowHeight)
 | |
|         {
 | |
|             Rectangle r2 = r;
 | |
|             Rectangle t = _GridContainer.SViewRect;
 | |
| 
 | |
|             if (r.IntersectsWith(t))
 | |
|                 r.Intersect(t);
 | |
| 
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 if (r2.Y < t.Y)
 | |
|                 {
 | |
|                     if (r.Height < rowHeight)
 | |
|                     {
 | |
|                         r.Y = r.Bottom - rowHeight;
 | |
|                         r.Height = rowHeight;
 | |
|                     }
 | |
|                 }
 | |
|                 else if (r2.Bottom > t.Bottom)
 | |
|                 {
 | |
|                     if (r.Height < rowHeight)
 | |
|                         r.Height = rowHeight;
 | |
|                 }
 | |
| 
 | |
|                 GridColumn cols = panel.Columns[map[cr.ColumnStart]];
 | |
|                 GridColumn cole = panel.Columns[map[cr.ColumnEnd - 1]];
 | |
| 
 | |
|                 if (r2.X < t.X && cole.Bounds.X < t.X)
 | |
|                 {
 | |
|                     if (r.Width < cole.BoundsRelative.Width)
 | |
|                     {
 | |
|                         r.X = r2.Right - cole.BoundsRelative.Width;
 | |
|                         r.Width = cole.BoundsRelative.Width;
 | |
|                     }
 | |
|                 }
 | |
|                 else if (r2.Right > t.Right && cols.Bounds.Right > r.Right)
 | |
|                 {
 | |
|                     if (r.Width < cols.BoundsRelative.Width)
 | |
|                     {
 | |
|                         r.X = r2.X;
 | |
|                         r.Width = cols.BoundsRelative.Width;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (r);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetRow
 | |
| 
 | |
|         private GridRow GetRow(int index)
 | |
|         {
 | |
|             return (_GridPanel.VirtualMode == true)
 | |
|                        ? _GridPanel.VirtualRows[index]
 | |
|                        : _GridContainer.Rows[index] as GridRow;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 |