/// <summary> /// Resets the merged row and column associated proeprties. /// </summary> /// <param name="dataRow"></param> internal void ResetCoveredRows(DataRowBase dataRow) { dataRow.VisibleColumns.ForEach (item => { if (!item.IsIndentColumn && !item.IsExpanderColumn) { if (this.dataGrid.VisualContainer.ScrollColumns.GetVisibleLineAtLineIndex(item.ColumnIndex) != null) { item.ColumnVisibility = Visibility.Visible; } if (item.IsSpannedColumn && dataRow.IsSpannedRow) { item.IsCurrentCell = false; } item.IsSelectedColumn = false; item.isSpannedColumn = false; } } ); dataRow.isSpannedRow = false; }
/// <summary> /// Raise event for merged row. /// </summary> /// <param name="dr"></param> internal void InitializeMergedRow(DataRowBase dr) { dr.VisibleColumns.ForEach(item => { if (CanQueryColumn(item)) { this.EnsureMergedCells(dr, item, dr.RowData); } }); }
internal void ValidateColumns(DataRowBase dr) { foreach (var column in dr.VisibleColumns) { if (column.GridColumn != null) { this.ValidateColumn(dr.RowData, column.GridColumn.MappingName, column.ColumnElement as GridCell, new RowColumnIndex(column.RowIndex, column.ColumnIndex)); } } }
internal override void CollapseDetailsViewAt(int rowIndex, DataRowBase dr, RecordEntry record) { if (dr != null) { dr.IsExpanded = false; if (record == null) { return; } foreach (var viewDefinition in this.DataGrid.DetailsViewDefinition) { if (viewDefinition is GridViewDefinition) { if (record.ChildViews != null && record.ChildViews.ContainsKey(viewDefinition.RelationalColumn)) { record.ChildViews[viewDefinition.RelationalColumn].IsNestedLevelExpanded = false; record.ChildViews[viewDefinition.RelationalColumn].ExpandedLevel = -1; } } } } else { if (record == null) { return; } if (!record.IsExpanded) { return; } record.IsExpanded = false; ResetExpandedLevel(this.DataGrid); var actualRowIndex = rowIndex; foreach (var viewDefinition in this.DataGrid.DetailsViewDefinition) { actualRowIndex++; if (viewDefinition is GridViewDefinition) { int repeatValueCount; if (record.ChildViews != null && record.ChildViews.ContainsKey(viewDefinition.RelationalColumn)) { record.ChildViews[viewDefinition.RelationalColumn].IsNestedLevelExpanded = false; record.ChildViews[viewDefinition.RelationalColumn].ExpandedLevel = -1; } var isHidden = this.DataGrid.VisualContainer.RowHeights.GetHidden(actualRowIndex, out repeatValueCount); if (!isHidden) { this.DataGrid.VisualContainer.RowHeights.SetHidden(actualRowIndex, actualRowIndex, true); this.DataGrid.VisualContainer.RowHeights.SetNestedLines(actualRowIndex, null); } } } } }
/// <summary> /// Gets the list of DataColumnBase that contains covered cell info for the specified DataRow. /// </summary> /// <param name="dataRow"> /// Specifies the corresponding DataRow to get the list of DataColumnBase. /// </param> /// <returns> /// Returns the collection of <see cref="Syncfusion.UI.Xaml.Grid.DataColumnBase"/> for the specified DataRow. /// </returns> public List <DataColumnBase> GetCoveredColumns(DataRowBase dataRow) { List <DataColumnBase> coveredColumns = new List <DataColumnBase>(); var coveredCellInfo = GetCoveredCellsRange(dataRow); if (coveredCellInfo.Count == 0) { return(coveredColumns); } coveredCellInfo.ForEach(info => { coveredColumns.Add(dataRow.VisibleColumns.Find(column => info.ContainsColumn(column.ColumnIndex))); }); return(coveredColumns); }
/// <summary> /// Update the mapped row's column index while scroll the punch of columns that has covered range has been removed. /// </summary> /// <param name="dr"></param> internal void UpdateMappedColumnIndex(DataRowBase dr) { var coveredCellInfoCollection = this.dataGrid.CoveredCells.GetCoveredCellsRange(dr).OrderBy(coveredRange => coveredRange.Top); if (coveredCellInfoCollection.Count() == 0) { return; } coveredCellInfoCollection.ForEach(coveredRange => { if (coveredRange.MappedRowColumnIndex.RowIndex == dr.RowIndex) { foreach (var column in dr.VisibleColumns) { if (column.IsSpannedColumn && coveredRange.ContainsColumn(column.ColumnIndex)) { if (column.ColumnVisibility == Visibility.Visible) { var visibleInfo = dataGrid.VisualContainer.ScrollColumns.GetVisibleLineAtLineIndex(column.ColumnIndex); if (visibleInfo.IsClippedOrigin) { coveredRange.MappedRowColumnIndex = new RowColumnIndex(coveredRange.MappedRowColumnIndex.RowIndex, column.ColumnIndex + 1 >= coveredRange.Right ? coveredRange.Right : column.ColumnIndex + 1); break; } else { coveredRange.MappedRowColumnIndex = new RowColumnIndex(coveredRange.MappedRowColumnIndex.RowIndex, column.ColumnIndex); break; } } else { continue; } } } if (dr.VisibleColumns.All(column => column.ColumnIndex != coveredRange.MappedRowColumnIndex.ColumnIndex)) { coveredRange.MappedRowColumnIndex = new RowColumnIndex(coveredRange.MappedRowColumnIndex.RowIndex, -1); } } }); }
/// <summary> /// Update the mapped row index while scroll the punch of columns that has covered range has been removed. /// </summary> /// <param name="dr"></param> /// <param name="actualStartIndex"></param> internal void UpdateMappedRowIndex(DataRowBase dr, int actualStartIndex) { var startRows = this.dataGrid.RowGenerator.Items.FindAll(item => item.RowIndex <= actualStartIndex && item.RowIndex > (this.dataGrid.HeaderLineCount - 1) && item.RowVisibility == Visibility.Visible); List <CoveredCellInfo> startRowCoveredRangeCollection = new List <CoveredCellInfo>(); foreach (DataRowBase mergedRow in startRows) { startRowCoveredRangeCollection.AddRange(this.dataGrid.CoveredCells.GetCoveredCellsRange(mergedRow)); } if (startRowCoveredRangeCollection.Count == 0) { return; } startRowCoveredRangeCollection.ForEach(coveredRange => { if (coveredRange.ContainsRow(dr.RowIndex)) { var dataRow = this.dataGrid.RowGenerator.Items.Find(item => item.RowVisibility == Visibility.Visible && item.RowIndex == actualStartIndex && dr.RowIndex == actualStartIndex); if (dataRow != null) { var visibleinfo = this.dataGrid.VisualContainer.ScrollRows.GetVisibleLineAtLineIndex(dataRow.RowIndex); if (visibleinfo != null && visibleinfo.IsClippedOrigin) { var nextTopRow = this.dataGrid.RowGenerator.Items.FirstOrDefault(item => item.RowVisibility == Visibility.Visible && item.RowIndex > actualStartIndex && item.RowIndex <= coveredRange.Bottom); if (nextTopRow != null) { coveredRange.MappedRowColumnIndex = new RowColumnIndex(nextTopRow.RowIndex, coveredRange.MappedRowColumnIndex.ColumnIndex); } else // when we load the bottom as it also clipped. { coveredRange.MappedRowColumnIndex = new RowColumnIndex(actualStartIndex, coveredRange.MappedRowColumnIndex.ColumnIndex); } } else { coveredRange.MappedRowColumnIndex = new RowColumnIndex(actualStartIndex, coveredRange.MappedRowColumnIndex.ColumnIndex); } } } }); }
/// <summary> /// Throws exception for the column other dataColumn. /// </summary> /// <param name="dataRow"></param> /// <param name="range"></param> internal void ContainsColumn(DataRowBase dataRow, CoveredCellInfo range) { var columns = dataRow.VisibleColumns.Where(column => column.ColumnIndex >= range.Left && column.ColumnIndex <= range.Right); if (!(columns.Any())) { return; } columns.ForEach(column => { if (range.ContainsColumn(column.ColumnIndex)) { if (!this.dataGrid.MergedCellManager.CanQueryColumn(column)) { throw new Exception(String.Format("Given range is not valid {0} with the column type {1}", column, column.IndentColumnType.ToString())); } } } ); }
/// <summary> /// Update merged rows column element and its properties - IsSpannedColumn, IsSpannedRow. /// </summary> /// <param name="dr"></param> internal void UpdateMergedRow(DataRowBase dr) { dr.VisibleColumns.ForEach(item => { // For Data manipulation - while add or remove rows. var coveredCellInfo = this.dataGrid.CoveredCells.GetCoveredCellInfo(item); if (this.dataGrid.VisualContainer.ScrollColumns.GetVisibleLineAtLineIndex(item.ColumnIndex) != null && coveredCellInfo != null && coveredCellInfo.MappedRowColumnIndex.RowIndex >= item.RowIndex && coveredCellInfo.MappedRowColumnIndex.RowIndex <= coveredCellInfo.Bottom && item.ColumnIndex >= coveredCellInfo.MappedRowColumnIndex.ColumnIndex && item.ColumnIndex <= coveredCellInfo.Right && item.ColumnVisibility == Visibility.Collapsed && item.GridColumn != null && !item.GridColumn.IsHidden) { item.ColumnVisibility = Visibility.Visible; // while scroll vertically - next to next meregd rows to change its column visibility. } else { // coveredinfo will be null while add new row above merged rows if (coveredCellInfo == null) { if (item.IsSpannedColumn && this.dataGrid.VisualContainer.ScrollColumns.GetVisibleLineAtLineIndex(item.ColumnIndex) != null) { item.isSpannedColumn = false; item.ColumnVisibility = Visibility.Visible; } } else { // have covered range but not false under the above conditions while remove rows - while remove row between meregd range, default row moved up and used as merged row. if (!item.IsSpannedColumn && (dr.RowType == RowType.DefaultRow || dr.RowType == RowType.UnBoundRow)) { this.EnsureMergedCells(dr, item, dr.RowData); } } } }); }
/// <summary> /// Method which help to update the error message for particular row based on validation applied on SfDataGrid. /// </summary> /// <param name="dataRow"> /// Contains the current datarow of SfDataGrid /// </param> /// <param name="removeAll">The bool variable used to remove validation error message</param> internal void RemoveError(DataRowBase dataRow, bool removeAll) { if (dataRow == null) { return; } foreach (DataColumnBase column in dataRow.VisibleColumns) { if (column.ColumnElement is GridCell) { var gridcell = column.ColumnElement as GridCell; if (removeAll) { gridcell.RemoveAll(); } else { gridcell.RemoveRowValidationError(); gridcell.RemoveCellValidationError(false); } } } dataRow.WholeRowElement.RemoveError(); }
/// <summary> /// Gets the CoveredCellInfo collection for the specified data row. /// </summary> /// <param name="dataRow"> /// Specifies the corresponding data row to get the CoveredCellInfo collection. /// </param> /// <returns> /// Returns the CoveredCellInfo collection for the specified data row /// </returns> public List <CoveredCellInfo> GetCoveredCellsRange(DataRowBase dataRow) { return(dataGrid.CoveredCells.FindAll(item => item.MappedRowColumnIndex.RowIndex == dataRow.RowIndex || item.ContainsRow(dataRow.RowIndex))); }
/// <summary> /// Raise query for the each column /// </summary> /// <param name="dataGrid"></param> /// <param name="dc"></param> internal void EnsureMergedCells(DataRowBase dr, DataColumnBase dc, object dataContext) { if (dc.GridColumn == null) { return; } var coveredCell = dataGrid.CoveredCells.GetCoveredCell(dc.RowIndex, dc.ColumnIndex, dc.GridColumn, dataContext); if (coveredCell == null) { return; } //Throws exception for invalid range with rows. this.dataGrid.CoveredCells.ContainsRow(coveredCell); // Throws exception for invalid range with columns. this.dataGrid.CoveredCells.ContainsColumn(dr, coveredCell); if (!dc.GridColumn.hasCellTemplate && (dc.GridColumn.hasCellTemplateSelector || (dc.GridColumn.IsTemplate && ((dc.GridColumn as GridTemplateColumn).hasEditTemplateSelector || dataGrid.hasCellTemplateSelector)))) // Column has cell template selector will not get merge. { this.dataGrid.CoveredCells.Remove(coveredCell); return; } // Raise exception for the invalid range of unbound row. if (dr.RowType == RowType.UnBoundRow) { var bottomIndex = coveredCell.Bottom; var topIndex = coveredCell.Top; RowRegion topRowRegion = dr.RowRegion; if (dataGrid.RowGenerator.Items.Find(row => row.RowIndex == topIndex) != null) { topRowRegion = dataGrid.RowGenerator.Items.Find(row => row.RowIndex == topIndex).RowRegion; } RowRegion bottomRowRegion = dr.RowRegion; if (dataGrid.RowGenerator.Items.Find(row => row.RowIndex == bottomIndex) != null) { bottomRowRegion = dataGrid.RowGenerator.Items.Find(row => row.RowIndex == bottomIndex).RowRegion; } if (!dataGrid.IsUnBoundRow(bottomIndex) || !dataGrid.IsUnBoundRow(topIndex) || topRowRegion != bottomRowRegion) { throw new Exception(string.Format("Given range {0} is not valid", coveredCell)); } } dr.isSpannedRow = true; dc.isSpannedColumn = true; // Reset the covered cell range by bottom for Frozen rows. if (dataGrid.FrozenRowsCount > 0 && coveredCell.Top < dataGrid.VisualContainer.FrozenRows) { CoveredCellInfo newCoveredCell = null; dataGrid.CoveredCells.Remove(coveredCell); if (coveredCell.Top < dataGrid.VisualContainer.FrozenRows && coveredCell.Bottom >= dataGrid.VisualContainer.FrozenRows) { newCoveredCell = new CoveredCellInfo(coveredCell.Left, coveredCell.Right, coveredCell.Top, coveredCell.Bottom < dataGrid.VisualContainer.FrozenRows ? coveredCell.Bottom : dataGrid.VisualContainer.FrozenRows - 1); } else { newCoveredCell = coveredCell; } dataGrid.CoveredCells.Add(newCoveredCell); this.UpdateMappedRowIndex(dr, dr.RowIndex); dataGrid.RowGenerator.Items.ForEach(row => { if (newCoveredCell != null && row.RowIndex > newCoveredCell.Bottom && row.RowIndex <= coveredCell.Bottom) { dataGrid.MergedCellManager.ResetCoveredRows(row); } } ); } // Reset the covered cell range by top for footer rows. else if (dataGrid.FooterRowsCount > 0 && coveredCell.Bottom >= (this.dataGrid.VisualContainer.RowCount - this.dataGrid.VisualContainer.FooterRows) && coveredCell.Bottom < this.dataGrid.VisualContainer.RowCount) { CoveredCellInfo newCoveredCell = null; dataGrid.CoveredCells.Remove(coveredCell); if (coveredCell.Top < (dataGrid.VisualContainer.RowCount - dataGrid.VisualContainer.FooterRows)) { newCoveredCell = new CoveredCellInfo(coveredCell.Left, coveredCell.Right, coveredCell.Top < (dataGrid.VisualContainer.RowCount - dataGrid.VisualContainer.FooterRows) ? (dataGrid.VisualContainer.RowCount - dataGrid.VisualContainer.FooterRows) : coveredCell.Top, coveredCell.Bottom); } else { newCoveredCell = coveredCell; } dataGrid.CoveredCells.Add(newCoveredCell); this.UpdateMappedRowIndex(dr, dr.RowIndex); dataGrid.RowGenerator.Items.ForEach(row => { if (newCoveredCell != null && row.RowIndex < newCoveredCell.Top && row.RowIndex >= coveredCell.Top) { dataGrid.MergedCellManager.ResetCoveredRows(row); } } ); } // Reset the covered cell range by right for frozen columns if (dataGrid.FrozenColumnCount > 0 && dc.ColumnIndex < dataGrid.VisualContainer.FrozenColumns) { CoveredCellInfo newCoveredCell = null; dataGrid.CoveredCells.Remove(coveredCell); if (coveredCell.Left < dataGrid.VisualContainer.FrozenColumns && coveredCell.Right >= dataGrid.VisualContainer.FrozenColumns) { newCoveredCell = new CoveredCellInfo(coveredCell.Left, coveredCell.Right < dataGrid.VisualContainer.FrozenColumns ? coveredCell.Right : dataGrid.VisualContainer.FrozenColumns - 1, coveredCell.Top, coveredCell.Bottom); } else { newCoveredCell = coveredCell; } dataGrid.CoveredCells.Add(newCoveredCell); this.UpdateMappedRowIndex(dr, dr.RowIndex); dataGrid.RowGenerator.Items.ForEach(row => { if (newCoveredCell != null && row.RowIndex >= coveredCell.Top && row.RowIndex <= coveredCell.Bottom) { row.VisibleColumns.ForEach(column => { if (column.ColumnIndex > newCoveredCell.Right && column.ColumnIndex <= coveredCell.Right) { column.isSpannedColumn = false; column.ColumnVisibility = Visibility.Visible; } }); } } ); } // Reset the covered cell range by left for frozen columns else if (dataGrid.FooterColumnCount > 0 && coveredCell.Right >= (dataGrid.VisualContainer.ColumnCount - dataGrid.VisualContainer.FooterColumns) && coveredCell.Right < dataGrid.VisualContainer.ColumnCount) { CoveredCellInfo newCoveredCell = null; dataGrid.CoveredCells.Remove(coveredCell); if ((dataGrid.VisualContainer.ColumnCount - dataGrid.VisualContainer.FooterColumns) >= coveredCell.Left && coveredCell.Right <= dataGrid.VisualContainer.ColumnCount) { newCoveredCell = new CoveredCellInfo(coveredCell.Left, coveredCell.Right < (dataGrid.VisualContainer.ColumnCount - dataGrid.VisualContainer.FooterColumns) ? coveredCell.Right : dataGrid.VisualContainer.ColumnCount - dataGrid.VisualContainer.FooterColumns, coveredCell.Top, coveredCell.Bottom); } else { newCoveredCell = coveredCell; } dataGrid.CoveredCells.Add(newCoveredCell); this.UpdateMappedRowIndex(dr, dr.RowIndex); dataGrid.RowGenerator.Items.ForEach(row => { if (newCoveredCell != null && row.RowIndex >= coveredCell.Top && row.RowIndex <= coveredCell.Bottom) { row.VisibleColumns.ForEach(column => { if (column.ColumnIndex > newCoveredCell.Right && column.ColumnIndex <= coveredCell.Right) { column.isSpannedColumn = false; column.ColumnVisibility = Visibility.Visible; } }); } } ); } }
/// <summary> /// Refresh the merged row within the range. /// </summary> /// <param name="dr"></param> internal void RefreshMergedRows(DataRowBase dr) { var coveredCellInfoCollection = this.dataGrid.CoveredCells.GetCoveredCellsRange(dr); if (coveredCellInfoCollection.Count == 0) { return; } foreach (var coveredRange in coveredCellInfoCollection) { var invalidateRows = this.dataGrid.RowGenerator.Items.FindAll(item => item.RowIndex <= coveredRange.Bottom && item.RowIndex >= coveredRange.Top && (item.RowType == RowType.DefaultRow || item.RowType == RowType.UnBoundRow)); foreach (var invalidateRow in invalidateRows) { if (invalidateRow.RowType == RowType.AddNewRow && (invalidateRow.RowIndex == coveredRange.Top || invalidateRow.RowIndex == coveredRange.Bottom)) { throw new Exception(String.Format("AddNewRow cells cannot be merged {0}", coveredRange)); } if (!invalidateRow.IsSpannedRow) { this.InitializeMergedRow(invalidateRow); } invalidateRow.VisibleColumns.ForEach(r => { var detailsViewDefinitionCount = this.dataGrid.DetailsViewDefinition.Count; if (detailsViewDefinitionCount != 0 && this.dataGrid.IsInDetailsViewIndex(invalidateRow.RowIndex + detailsViewDefinitionCount)) { var throwException = false; foreach (var viewDefinition in this.dataGrid.DetailsViewDefinition) { var itemSource = this.dataGrid.DetailsViewManager.GetChildSource(dr.RowData, viewDefinition.RelationalColumn); if (DetailsViewHelper.GetChildSourceCount(itemSource) > 0) { throwException = true; break; } } if (invalidateRow.RowIndex != coveredRange.Bottom && (throwException || !dataGrid.HideEmptyGridViewDefinition)) { throw new Exception(String.Format("Given range is not valid {0} with the details view row", coveredRange)); } } if (r.ColumnIndex >= coveredRange.Left && r.ColumnIndex <= coveredRange.Right && r.GridColumn != null && !r.GridColumn.IsHidden) { if (r.ColumnVisibility == Visibility.Collapsed) { r.ColumnVisibility = Visibility.Visible; } } } ); if (!this.dataGrid.IsInDetailsViewIndex(invalidateRow.RowIndex)) { invalidateRow.WholeRowElement.ItemsPanel.InvalidateMeasure(); invalidateRow.WholeRowElement.ItemsPanel.InvalidateArrange(); #if WPF if (this.dataGrid.useDrawing) { invalidateRow.WholeRowElement.ItemsPanel.InvalidateVisual(); } #endif } } } }