/// <summary> /// Throws exception for the row other DataRow/UnBound Row that tries to span /// </summary> /// <param name="range"></param> internal void ContainsRow(CoveredCellInfo range) { var rows = dataGrid.RowGenerator.Items.Where(row => row.RowIndex >= range.Top && row.RowIndex <= range.Bottom); if (!(rows.Any())) { return; } rows.ForEach(row => { if (range.ContainsRow(row.RowIndex) && (row.RowType != RowType.DefaultRow && row.RowType != RowType.UnBoundRow || row.RowType == RowType.AddNewRow)) { throw new Exception(string.Format("Given range {0} is not valid with the row type {1}", range, row.RowType)); } // Throw exception when the invalid parent row merges. if (this.dataGrid.DetailsViewDefinition.Count > 0 && this.dataGrid.IsInDetailsViewIndex(row.RowIndex + this.dataGrid.DetailsViewDefinition.Count)) { foreach (var viewDefinition in this.dataGrid.DetailsViewDefinition) { var itemSource = this.dataGrid.DetailsViewManager.GetChildSource(row.RowData, viewDefinition.RelationalColumn); if (DetailsViewHelper.GetChildSourceCount(itemSource) > 0) { throw new Exception(string.Format("Given range {0} is not valid with the details view row", range)); } } } }); }
/// <summary> /// While reusing DetailsViewDataRow, need to clear DetailsViewDataGrid properties /// </summary> /// <param name="view">DetailsViewDataGrid's view</param> internal static void ClearViewProperties(ICollectionViewAdv view) { // Check view is in Defer refresh var isIndeferRefresh = view.IsInDeferRefresh; if (view.SortDescriptions != null && view.SortDescriptions.Any()) { DetailsViewHelper.BeginInit(view); view.SortDescriptions.Clear(); } if (view.FilterPredicates != null && view.FilterPredicates.Any()) { DetailsViewHelper.BeginInit(view); view.FilterPredicates.Clear(); } if (view.GroupDescriptions != null && view.GroupDescriptions.Any()) { DetailsViewHelper.BeginInit(view); view.GroupDescriptions.Clear(); } if (view.SortComparers != null && view.SortComparers.Any()) { DetailsViewHelper.BeginInit(view); view.SortComparers.Clear(); } if (view.Filter != null) { DetailsViewHelper.BeginInit(view); view.Filter = null; } if (view.GroupComparer != null) { DetailsViewHelper.BeginInit(view); view.GroupComparer = null; } if (view.CaptionSummaryRow != null) { DetailsViewHelper.BeginInit(view); view.CaptionSummaryRow = null; } if (view.SummaryRows != null && view.SummaryRows.Any()) { DetailsViewHelper.BeginInit(view); view.SummaryRows.Clear(); } if (view.TableSummaryRows != null && view.TableSummaryRows.Any()) { DetailsViewHelper.BeginInit(view); view.TableSummaryRows.Clear(); } // If view is in DeferRefresh and already BeginInit is not called, need to call EndInit if (view.IsInDeferRefresh && !isIndeferRefresh) { view.EndInit(); } }
/// <summary> /// Check whther any othe childview contains records /// </summary> /// <param name="record">RecordEntry</param> /// <returns>true if any child contains record</returns> internal static bool HasChildSource(this DetailsViewManager manager, RecordEntry record) { var provider = manager.DataGrid.View.GetPropertyAccessProvider(); foreach (var definition in manager.DataGrid.DetailsViewDefinition) { var childSource = provider.GetValue(record.Data, definition.RelationalColumn) as IEnumerable; if (childSource != null && DetailsViewHelper.GetChildSourceCount(childSource) > 0) { return(true); } } return(false); }
/// <summary> /// Decides whether to merge the adjacent parent rows based on child source of row data. /// </summary> /// <param name="dataGrid">The SfDataGrid.</param> /// <param name="rowData">Specifies the data object to find the child items source.</param> /// <returns> /// Returns <b>true</b> if the DetialsViewDataGrid has items source; otherwise, <b>false</b>. /// </returns> public static bool CanMergeNextRows(this SfDataGrid dataGrid, object rowData) { if (!dataGrid.HideEmptyGridViewDefinition) { return(false); } foreach (var viewDefinition in dataGrid.DetailsViewDefinition) { var itemSource = dataGrid.DetailsViewManager.GetChildSource(rowData, viewDefinition.RelationalColumn); if (DetailsViewHelper.GetChildSourceCount(itemSource) > 0) { return(false); } } return(true); }
internal static int GetChildSourceCount(object source) { //(WPF -37043) To avoid break the below method is called here. return(DetailsViewHelper.GetChildSourceCount(source)); }
internal override List <int> ExpandDetailsView(int rowIndex, RecordEntry record, Dictionary <string, IEnumerable> detailsViewItemsSource) { var actualRowIndex = rowIndex; record.IsExpanded = true; ResetExpandedLevel(this.DataGrid); var count = 0; var updateDataRow = new List <int>(); var DetailsViewDefinition = this.DataGrid.DetailsViewDefinition; // If the grid is DetailsViewDataGrid, need to access SourceDataGrid's DetailsViewDefinition(Since NotifyListener is assigned for SourceDataGrid's DetailsViewDefinition only) if (this.DataGrid is DetailsViewDataGrid && this.DataGrid.NotifyListener != null) { DetailsViewDefinition = this.DataGrid.NotifyListener.SourceDataGrid.DetailsViewDefinition; } foreach (var detailsView in DetailsViewDefinition) { actualRowIndex++; var gridViewDefinition = detailsView as GridViewDefinition; IEnumerable itemsSource; if (detailsViewItemsSource.TryGetValue(gridViewDefinition.RelationalColumn, out itemsSource) && itemsSource != null) { CreateOrUpdateDetailsViewDataRow(this.DataGrid.RowGenerator.Items, actualRowIndex, record, detailsView, count, itemsSource); } else if (!this.DataGrid.HideEmptyGridViewDefinition) { CreateOrUpdateDetailsViewDataRow(this.DataGrid.RowGenerator.Items, actualRowIndex, record, detailsView, count, null); } // WPF-20080 - When HideEmptyGridViewDefinition is true and there is no records in details view, need to hide DetailsViewDataRow else { // WPF-19997 - Create childView only if HideEmptyGridViewDefinition if (!record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn)) { record.ChildViews.Add(gridViewDefinition.RelationalColumn, new NestedRecordEntry(record, record.Level) { NestedLevel = (actualRowIndex - rowIndex) - 1 }); ResetTopLevelGroupCache(); } count++; updateDataRow.Add(actualRowIndex); this.DataGrid.VisualContainer.RowHeights.SetHidden(actualRowIndex, actualRowIndex, true); continue; } updateDataRow.Add(actualRowIndex); var view = record.ChildViews[gridViewDefinition.RelationalColumn]; if (view != null && !this.DataGrid.HideEmptyGridViewDefinition) { this.DataGrid.VisualContainer.RowHeights.SetHidden(actualRowIndex, actualRowIndex, false); } else if (view != null && DetailsViewHelper.GetChildSourceCount(view.View.SourceCollection) > 0) { this.DataGrid.VisualContainer.RowHeights.SetHidden(actualRowIndex, actualRowIndex, false); } else { this.DataGrid.VisualContainer.RowHeights.SetHidden(actualRowIndex, actualRowIndex, true); } count++; } if (this.DataGrid.HideEmptyGridViewDefinition) { if (record.ChildViews.Count == this.DataGrid.DetailsViewDefinition.Count) { var isExpanded = record.ChildViews.Any(view => view.Value.View != null && DetailsViewHelper.GetChildSourceCount(view.Value.View.SourceCollection) > 0); if (!isExpanded) { var recordIndex = this.DataGrid.ResolveToRecordIndex(rowIndex); this.DataGrid.DetailsViewManager.CollapseDetailsViewAt(recordIndex); } } } return(updateDataRow); }
internal override void ExpandNestedLinesofRecord(IEnumerable itemsSource, LineSizeCollection lines, GridViewDefinition gridViewDefinition, RecordEntry recordEntry, int level) { if (gridViewDefinition.DataGrid.DetailsViewDefinition != null && gridViewDefinition.DataGrid.DetailsViewDefinition.Any()) { var rowIndex = 1; foreach (var item in itemsSource) { var actualRowIndex = rowIndex; int index = 0; foreach (var nestedViewDefinition in gridViewDefinition.DataGrid.DetailsViewDefinition) { if (nestedViewDefinition is GridViewDefinition) { index++; var nestedgridViewDefinition = nestedViewDefinition as GridViewDefinition; actualRowIndex++; int repeatValueCount; var isHidden = lines.GetHidden(actualRowIndex, out repeatValueCount); LineSizeCollection nestedLines = null; if (!isHidden) { nestedLines = lines.GetNestedLines(actualRowIndex) as LineSizeCollection; } int nestedLevel = recordEntry != null && recordEntry.ChildViews != null && recordEntry.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn) ? recordEntry.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel : level; if (nestedLines == null) { var detailsViewLinesitemsource = GetChildSource((item is RecordEntry) ? (item as RecordEntry).Data : item, nestedgridViewDefinition.RelationalColumn); int count = 0; // If need to expand inner levels also, DetailsViewDefinition count is added with SourceCollection count if (nestedLevel > this.DataGrid.DetailsViewManager.GetDefinitionLevel(nestedgridViewDefinition) || nestedLevel == -1) { count = detailsViewLinesitemsource != null?DetailsViewHelper.GetChildSourceCount(detailsViewLinesitemsource) * (nestedgridViewDefinition.DataGrid.DetailsViewDefinition.Count + 1) : 0; } else { count = detailsViewLinesitemsource != null?DetailsViewHelper.GetChildSourceCount(detailsViewLinesitemsource) : 0; } // While creating lines, LineCount is set by considering DetailsViewDataRow also. But if we HideEmptyGridViewDefintion is true, we need to hide it(RowHeight = 0) if (nestedgridViewDefinition.DataGrid.HideEmptyGridViewDefinition && count == 0) { lines.SetHidden(actualRowIndex, actualRowIndex, true); continue; } //AddNewRow, StackedHeaders, UnBoundRows and TableSummaryRows count added here count += nestedgridViewDefinition.DataGrid.StackedHeaderRows != null ? nestedgridViewDefinition.DataGrid.StackedHeaderRows.Count : 0; count += nestedgridViewDefinition.DataGrid.UnBoundRows != null ? nestedgridViewDefinition.DataGrid.UnBoundRows.Count : 0; count += nestedgridViewDefinition.DataGrid.TableSummaryRows != null ? nestedgridViewDefinition.DataGrid.TableSummaryRows.Count : 0; count += nestedgridViewDefinition.DataGrid.AddNewRowPosition != AddNewRowPosition.None ? 1 : 0; nestedLines = new LineSizeCollection { LineCount = count + 1, DefaultLineSize = nestedgridViewDefinition.DataGrid.RowHeight }; } // Below code is to set the PaddingDistance based on GridViewDefintion level if (nestedgridViewDefinition.DataGrid.AllowDetailsViewPadding) { SetDetailsViewPadding(nestedLines, (item is RecordEntry) ? (item as RecordEntry).Data : item, rowIndex, actualRowIndex, gridViewDefinition.DataGrid); } if (nestedLevel > this.DataGrid.DetailsViewManager.GetDefinitionLevel(nestedgridViewDefinition) || nestedLevel == -1) { ExpandNestedLines((item is RecordEntry) ? (item as RecordEntry).Data : item, nestedLines, nestedgridViewDefinition, (item is RecordEntry) ? item as RecordEntry : null, nestedLevel); } lines.SetNestedLines(actualRowIndex, nestedLines); lines.SetHidden(actualRowIndex, actualRowIndex, false); } } rowIndex += gridViewDefinition.DataGrid.DetailsViewDefinition.Count + 1; } } }
internal override void InitializeDetailsViewRow(int rowIndex, RecordEntry record, DetailsViewDataRow detailsViewDataRow, int detailsViewIndex, ViewDefinition detailsView, IEnumerable itemsSource) { if (detailsView is GridViewDefinition) { var gridViewDefinition = detailsView as GridViewDefinition; if (gridViewDefinition.NotifyListener == null) { gridViewDefinition.NotifyListener = new DetailsViewNotifyListener(gridViewDefinition.DataGrid, this.DataGrid); } int repeatValueCount; var isHidden = this.DataGrid.VisualContainer.RowHeights.GetHidden(rowIndex, out repeatValueCount); if (detailsViewDataRow.DetailsViewDataGrid == null) { var grid = gridViewDefinition.NotifyListener.CopyPropertiesFromSourceDataGrid(gridViewDefinition.DataGrid); (grid.NotifyListener as DetailsViewNotifyListener)._parentDataGrid = this.DataGrid; // Apply style for DetailsViewDataGrid if (this.DataGrid.ReadLocalValue(SfDataGrid.DetailsViewDataGridStyleProperty) != DependencyProperty.UnsetValue) { grid.Style = this.DataGrid.DetailsViewDataGridStyle; } //grid.VisualContainer.ScrollOwner = this.DataGrid.VisualContainer.ScrollOwner; detailsViewDataRow.DetailsViewDataGrid = grid; } (detailsViewDataRow.DetailsViewDataGrid.NotifyListener as DetailsViewNotifyListener)._parentDataGrid = this.DataGrid; bool needtoinvalidatelinecollection = false; if (record.ChildViews != null && record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn) && record.ChildViews[gridViewDefinition.RelationalColumn].View != null) { var recordView = record.ChildViews[gridViewDefinition.RelationalColumn].View; if (detailsViewDataRow.DetailsViewDataGrid.View == recordView) { // If we assign new RowHeights in CreateOrUpdateDetailsViewDataRow, need to update Row and Column count here if (detailsViewDataRow.DetailsViewDataGrid.VisualContainer.RowHeights.TotalExtent == 0) { detailsViewDataRow.DetailsViewDataGrid.RefreshHeaderLineCount(); detailsViewDataRow.DetailsViewDataGrid.UpdateRowAndColumnCount(false); detailsViewDataRow.DetailsViewDataGrid.RowGenerator.Items.ForEach(item => item.RowIndex = -1); } // Need to update DataGrid in CollectionView if (detailsViewDataRow.DetailsViewDataGrid.View is IGridViewNotifier) { (detailsViewDataRow.DetailsViewDataGrid.View as IGridViewNotifier).AttachGridView(detailsViewDataRow.DetailsViewDataGrid); } } if (detailsViewDataRow.DetailsViewDataGrid.View != recordView) { detailsViewDataRow.RowData = recordView.SourceCollection; // Remove detailsview grid from ClonedDataGrid list UpdateClonedDataGrid(detailsViewDataRow); // WPF-22862 - in some cases, recordView is view of some DetailsViewDataGrid. But it will not be taken for reuse. // So need to unwire events from that DetailsViewDataGrid if (recordView is IGridViewNotifier) { var grid = (recordView as IGridViewNotifier).GetDataGrid(); if (grid is SfDataGrid) { var dataGrid = grid as SfDataGrid; dataGrid.GridModel.UnWireEvents(false); (recordView as IGridViewNotifier).DetachGridView(); dataGrid.suspendItemsSourceChanged = true; dataGrid.ItemsSource = null; dataGrid.View = null; dataGrid.RefreshHeaderLineCount(); dataGrid.UpdateRowAndColumnCount(false); dataGrid.suspendItemsSourceChanged = false; } } // While reusing view, need to clear previous view properties. Because properties will be updated in DetailsViewDataGrid only DetailsViewHelper.ClearViewProperties(recordView); detailsViewDataRow.DetailsViewDataGrid.ItemsSource = recordView; } // Expand the records in DetailsViewDataGrid based on IsNestedLevelExpanded and ExpandedLevel if (record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded || record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel > 1) { detailsViewDataRow.DetailsViewDataGrid.DetailsViewManager.ExpandAllDetailsView(record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded ? -1 : record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel - 1); } else { // If DetailsViewDataGrid's record is already expanded, need to collapse it if (record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel != -1) { detailsViewDataRow.DetailsViewDataGrid.CollapseAllDetailsView(); } } if (detailsViewDataRow.DetailsViewDataGrid.View != null) { foreach (var childrecord in detailsViewDataRow.DetailsViewDataGrid.View.Records.Where(r => r.IsExpanded)) { for (int i = 1; i <= detailsViewDataRow.DetailsViewDataGrid.DetailsViewDefinition.Count; i++) { var childRowIndex = detailsViewDataRow.DetailsViewDataGrid.ResolveToRowIndex(childrecord); int valueCount; if (detailsViewDataRow.DetailsViewDataGrid.VisualContainer.RowHeights.GetHidden(childRowIndex + i, out valueCount)) { detailsViewDataRow.DetailsViewDataGrid.VisualContainer.RowHeights.SetHidden(childRowIndex + i, childRowIndex + i, false); } } } } } else { if (itemsSource == null) { itemsSource = GetChildSource(record.Data, gridViewDefinition.RelationalColumn); } // If itemssource is same, we need to set itemssource as null. if (detailsViewDataRow.DetailsViewDataGrid.ItemsSource == itemsSource) { // Remove detailsview grid from ClonedDataGrid list UpdateClonedDataGrid(detailsViewDataRow); detailsViewDataRow.DetailsViewDataGrid.ItemsSource = null; // if itemsSource and DetailsViewDataGrid's itemssource is null, need to update RowCount here(since itemssourcechanged callback will not be called) if (itemsSource == null) { detailsViewDataRow.DetailsViewDataGrid.RefreshHeaderLineCount(); detailsViewDataRow.DetailsViewDataGrid.UpdateRowAndColumnCount(false); } } else { needtoinvalidatelinecollection = true; } detailsViewDataRow.RowData = itemsSource; // Remove detailsview grid from ClonedDataGrid list UpdateClonedDataGrid(detailsViewDataRow); detailsViewDataRow.DetailsViewDataGrid.ItemsSource = detailsViewDataRow.RowData; // Expand the records in DetailsViewDataGrid based on IsNestedLevelExpanded and ExpandedLevel if (!isHidden && ((record.ChildViews != null && record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn) && record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel > 1) || (record.ChildViews != null && record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn) && record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded))) { detailsViewDataRow.DetailsViewDataGrid.DetailsViewManager.ExpandAllDetailsView(record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded ? -1 : record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel - 1); } else { // If DetailsViewDataGrid's record is already expanded, need to collapse it if (record.ChildViews != null && record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn) && record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel != -1) { detailsViewDataRow.DetailsViewDataGrid.CollapseAllDetailsView(); } } var isNestedExpanded = false; var level = 0; if (record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn)) { isNestedExpanded = record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded; level = record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel; } record.ChildViews.Remove(gridViewDefinition.RelationalColumn); record.PopulateChildView(detailsViewDataRow.DetailsViewDataGrid.View, detailsViewIndex, gridViewDefinition.RelationalColumn, isNestedExpanded); record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel = level; ResetTopLevelGroupCache(); } if (detailsViewDataRow.WholeRowElement != null) { if (this.DataGrid.HideEmptyGridViewDefinition) { ApplyVisualState(rowIndex, record, detailsViewDataRow); } else { detailsViewDataRow.ApplyContentVisualState(detailsViewIndex == this.DataGrid.DetailsViewDefinition.Count - 1 ? "LastCell" : "NormalCell"); } } // Set PaddingDistance for DetailsViewDataGrid if (detailsViewDataRow.DetailsViewDataGrid.AllowDetailsViewPadding) { var paddingDistance = detailsViewDataRow.DetailsViewDataGrid.DetailsViewPadding.Top + detailsViewDataRow.DetailsViewDataGrid.DetailsViewPadding.Bottom + 1; if (detailsViewIndex == this.DataGrid.DetailsViewDefinition.Count - 1 || detailsViewDataRow.DetailsViewContentPresenter.CurrentVisualState == "LastCell") { paddingDistance += 1; } detailsViewDataRow.DetailsViewDataGrid.VisualContainer.RowHeights.PaddingDistance = paddingDistance; } this.DataGrid.VisualContainer.RowHeights.SetNestedLines(rowIndex, detailsViewDataRow.DetailsViewDataGrid.VisualContainer.RowHeights); if (detailsViewDataRow.DetailsViewDataGrid.View != null && detailsViewDataRow.DetailsViewDataGrid.Columns.Any(column => column.FilterPredicates.Any())) { detailsViewDataRow.DetailsViewDataGrid.GridModel.ApplyFilter(); // WPF-18240 - While expanding the record fist time, detailsview data row will not be added to parent grid. So unable to invalidate nested lines in RefreshParentDataGrid method // Below code is added to invalidate nested lines when filtering is applied //var lineCollection = (this.DataGrid.VisualContainer.RowHeights as LineSizeCollection); //if (lineCollection != null && lineCollection.Distances is DistanceRangeCounterCollection) // (lineCollection.Distances as DistanceRangeCounterCollection).InvalidateNestedEntry(rowIndex); needtoinvalidatelinecollection = true; } #if WPF if (detailsViewDataRow.DetailsViewDataGrid.SearchHelper.AllowFiltering) { detailsViewDataRow.DetailsViewDataGrid.View.Filter = detailsViewDataRow.DetailsViewDataGrid.SearchHelper.FilterRecords; detailsViewDataRow.DetailsViewDataGrid.View.RefreshFilter(); needtoinvalidatelinecollection = true; } #endif if (needtoinvalidatelinecollection) { var lineCollection = (this.DataGrid.VisualContainer.RowHeights as LineSizeCollection); if (lineCollection != null && lineCollection.Distances is DistanceRangeCounterCollection) { (lineCollection.Distances as DistanceRangeCounterCollection).InvalidateNestedEntry(rowIndex); } } detailsViewDataRow.DetailsViewDataGrid.DetailsViewManager.UpdateExtendedWidth(); //(WPF - 37043) When Child grid's columnsizer is Star, Parent Grid's width need not to be adjusted. if (detailsViewDataRow.DetailsViewDataGrid.ColumnSizer != GridLengthUnitType.Star) { AdjustParentsWidth(this.DataGrid, detailsViewDataRow.DetailsViewDataGrid, rowIndex); } // To refresh parent grid height in case of multi level nested grid and grouping DetailsViewHelper.RefreshParentDataGridRows(detailsViewDataRow.DetailsViewDataGrid); } }
internal override void ExpandAllDetailsViewOfRecord(int level, RecordEntry record, int rowIndex) { var actualRowIndex = rowIndex; int index = 0; foreach (var viewDefinition in this.DataGrid.DetailsViewDefinition) { actualRowIndex++; if (viewDefinition is GridViewDefinition) { index++; var gridViewDefinition = viewDefinition as GridViewDefinition; int repeatValueCount; var isHidden = this.DataGrid.VisualContainer.RowHeights.GetHidden(actualRowIndex, out repeatValueCount); LineSizeCollection lines = null; if (!isHidden) { lines = this.DataGrid.VisualContainer.RowHeights.GetNestedLines(actualRowIndex) as LineSizeCollection; } //WPF-18239 - If nested lines are reset, lines will be null(even though it is visible). // Below code is added to create nested lines if (lines == null) { var itemsource = GetChildSource(record.Data, gridViewDefinition.RelationalColumn); int count = 0; // If need to expand inner levels also, DetailsViewDefinition count is added with SourceCollection count if (level > 1 || level == -1) { count = itemsource != null?DetailsViewHelper.GetChildSourceCount(itemsource) * (gridViewDefinition.DataGrid.DetailsViewDefinition.Count + 1) : 0; } else { count = itemsource != null?DetailsViewHelper.GetChildSourceCount(itemsource) : 0; } if (this.DataGrid.HideEmptyGridViewDefinition && count == 0) { // WPF-19997 - Create childView only if HideEmptyGridViewDefinition if (!record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn)) { record.ChildViews.Add(gridViewDefinition.RelationalColumn, new NestedRecordEntry(record, record.Level) { NestedLevel = (actualRowIndex - rowIndex) - 1 }); this.ResetTopLevelGroupCache(); } continue; } // AddNewRow, StackedHeaders, UnBoundRows and TableSummaryRows count added here count += gridViewDefinition.DataGrid.StackedHeaderRows != null ? gridViewDefinition.DataGrid.StackedHeaderRows.Count : 0; count += gridViewDefinition.DataGrid.UnBoundRows != null ? gridViewDefinition.DataGrid.UnBoundRows.Count : 0; count += gridViewDefinition.DataGrid.TableSummaryRows != null ? gridViewDefinition.DataGrid.TableSummaryRows.Count : 0; count += gridViewDefinition.DataGrid.AddNewRowPosition != AddNewRowPosition.None ? 1 : 0; count += gridViewDefinition.DataGrid.FilterRowPosition != FilterRowPosition.None ? 1 : 0; // DefaultLineSize should be set based on the SourceDataGrid's RowHeight lines = new LineSizeCollection { LineCount = count + 1, DefaultLineSize = gridViewDefinition.DataGrid.RowHeight }; } // Below code is to set the PaddingDistance based on GridViewDefintion level if (this.DataGrid.AllowDetailsViewPadding) { SetDetailsViewPadding(lines, record.Data, rowIndex, actualRowIndex, this.DataGrid); } // Need to expand nested lines also if level is greater than 1 or need to expand all records (level is -1) if (level > 1 || level == -1) { ExpandNestedLines(record.Data, lines, gridViewDefinition, record, level); } this.DataGrid.VisualContainer.RowHeights.SetNestedLines(actualRowIndex, lines); this.DataGrid.VisualContainer.RowHeights.SetHidden(actualRowIndex, actualRowIndex, false); if (!record.ChildViews.ContainsKey(gridViewDefinition.RelationalColumn)) { record.ChildViews.Add(gridViewDefinition.RelationalColumn, new NestedRecordEntry(record, record.Level) { NestedLevel = (actualRowIndex - rowIndex) - 1 }); ResetTopLevelGroupCache(); } record.ChildViews[gridViewDefinition.RelationalColumn].ExpandedLevel = level; // Set IsNestedLevelExpanded if level is -1 (ExpandAllDetailsView is called) if (level == -1) { record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded = true; } else { record.ChildViews[gridViewDefinition.RelationalColumn].IsNestedLevelExpanded = false; } } } }
/// <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 } } } }