Hi,
I need to achieve simple merging of cells as in the following example. What is not clear to me from the description in the documentation is how this left-right etc. applies while selecting the cells.
From this:
| Value1 | Value2 | Value3 | Value4_1 |
| Value1 | Value2 | Value3 | Value4_2 |
| Value1 | Value2 | Value3 | Value4_1 |
| Value4_2 |
This is basically to merge all rows that have the same values in each column except the last one.
Thank you in advance,
Hi Biljana,
Your requirement to merge cells depends on the content is achievable by using
SfDataGrid.ItemsSourceChanged, SfDataGrid.QueryCoveredRange events. Please refer
the below user guide documentation for more information,
UG Link: https://help.syncfusion.com/wpf/datagrid/merge-cells#merging-cells-based-on-the-content
We have prepared the sample based on your scenario. Please find the sample in the attachment and let us know if you have any concerns in this.
Regards,
Dhanasekar M.
If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.
Hello,
Thank you for the answer. Actually I know of this sample, but it doesn`t do what is requested. It merges per column.
That is, from this:
| Value1 | Value2_1 | Value3 | Value4_1 |
| Value1 | Value2_1 | Value3 | Value4_2 |
| Value1 | Value2_2 | Value3 | Value4_1 |
| Value1 | Value2_2 | Value3 | Value4_1 |
it gets this:
| Value1 | Value2_1 | Value3 | Value4_1 |
| Value2_2 | Value4_2 |
While the request is to get this:
| Value1 | Value2_1 | Value3 | Value4_1 |
| Value4_2 | |||
| Value1 | Value2_2 | Value3 | Value4_1 |
| Value4_1 |
i.e. merge only the rows which have the same value in each column until the last one.
Nevertheless, I will be using a different solution. as this one is a bit complex for me.
Kind Regards,
Hi Biljana,
We are a little unclear about your scenario. By default, the cell merging is applied depending on the given range or the content present in the cell. We have checked the provided illustration, in this, you mentioned that the cell gets merged when all columns have the same value, but in your illustration the last column does not merge even though all data have the same value shown below,
And the provided illustrations are different from both
scenarios (Range and content). Like the complex merging (combining both) like
merging the cell based on the index. If we misunderstood your requirement, can
you please provide more information related to your requirement based on
that we will proceed with this further.
Regards,
Dhanasekar M.
Hi,
That which you marked was my mistake. In the initial message is 4_1; 4_2.
The request was to get this
| Value1 | Value2_1 | Value3 | Value4_1 |
| Value4_2 | |||
| Value1 | Value2_2 | Value3 | Value4_1 |
| Value4_2 |
merge the columns only if all columns of a row except the last one in this case, have the same value.
Kind Regards,
Hi Biljana,
Currently, we are checking the feasibility to achieve your
requirement on our end. We will check and update you with further details
on September 30, 2022.
We appreciate your patience until then.
Regards,
Dhanasekar M.
Hi Biljana,
Your requirement can be achieved by customizing the GetRange method and QueryCoveredRange event in SfDataGrid. Please refer to the below code snippet,
|
{ // here skip the merging for particular columns in SfDataGrid. // Skipped the last column as you required. if (e.GridColumn.MappingName == "Col4") return;
var range = GetRange(e.GridColumn, e.RowColumnIndex.RowIndex, e.RowColumnIndex.ColumnIndex, e.Record);
if (range == null) return;
// You can know that the range is already exist in Covered Cells by IsInRange method.
if (!dataGrid.CoveredCells.IsInRange(range)) { e.Range = range; e.Handled = true; }
//If the calculated range is already existed in CoveredCells, you can get the range using SfDataGrid.GetConflictRange (CoveredCellInfo coveredCellInfo) extension method. } { var range = new CoveredCellInfo(columnIndex, columnIndex, rowIndex, rowIndex); object data = reflector.GetFormattedValue(rowData, column.MappingName);
GridColumn leftColumn = null; GridColumn rightColumn = null;
// total rows count. int recordsCount = this.dataGrid.GroupColumnDescriptions.Count != 0 ? (this.dataGrid.View.TopLevelGroup.DisplayElements.Count + this.dataGrid.TableSummaryRows.Count + this.dataGrid.UnBoundRows.Count + (this.dataGrid.AddNewRowPosition == AddNewRowPosition.Top ? +1 : 0)) : (this.dataGrid.View.Records.Count + this.dataGrid.TableSummaryRows.Count + this.dataGrid.UnBoundRows.Count + (this.dataGrid.AddNewRowPosition == AddNewRowPosition.Top ? +1 : 0));
// Merge Horizontally
// compare right column
for (int i = dataGrid.Columns.IndexOf(column); i < this.dataGrid.Columns.Count - 1; i++) { var compareData = reflector.GetFormattedValue(rowData, dataGrid.Columns[i + 1].MappingName);
if (compareData == null) break;
if (!compareData.Equals(data)) break; rightColumn = dataGrid.Columns[i + 1]; }
// compare left column.
for (int i = dataGrid.Columns.IndexOf(column); i > 0; i--) { var compareData = reflector.GetFormattedValue(rowData, dataGrid.Columns[i - 1].MappingName);
if (compareData == null) break;
if (!compareData.Equals(data)) break; leftColumn = dataGrid.Columns[i - 1]; }
if (leftColumn != null || rightColumn != null) {
// set left index
if (leftColumn != null) { var leftColumnIndex = this.dataGrid.ResolveToScrollColumnIndex(this.dataGrid.Columns.IndexOf(leftColumn)); range = new CoveredCellInfo(leftColumnIndex, range.Right, range.Top, range.Bottom); }
// set right index
if (rightColumn != null) { var rightColumnIndex = this.dataGrid.ResolveToScrollColumnIndex(this.dataGrid.Columns.IndexOf(rightColumn)); range = new CoveredCellInfo(range.Left, rightColumnIndex, range.Top, range.Bottom); } return range; }
// Merge Vertically from the row index.
int previousRowIndex = -1; int nextRowIndex = -1;
// Get previous row data. var startIndex = dataGrid.ResolveStartIndexBasedOnPosition();
for (int i = rowIndex - 1; i >= startIndex; i--) { var previousData = this.dataGrid.GetRecordEntryAtRowIndex(i);
if (previousData == null || !previousData.IsRecords) break; var compareData = reflector.GetFormattedValue((previousData as RecordEntry).Data, column.MappingName);
if (compareData == null) break;
//here skip the merging when different values contains on the Col2 var previousCol2 = reflector.GetFormattedValue((previousData as RecordEntry).Data, "Col2");
object rowDataCol2 = reflector.GetFormattedValue(rowData, "Col2");
if (!compareData.Equals(data) || !previousCol2.Equals(rowDataCol2)) break;
previousRowIndex = i; }
// get next row data.
for (int i = rowIndex + 1; i < recordsCount + 1; i++) { var nextData = this.dataGrid.GetRecordEntryAtRowIndex(i);
if (nextData == null || !nextData.IsRecords) break; var compareData = reflector.GetFormattedValue((nextData as RecordEntry).Data, column.MappingName);
if (compareData == null) break;
//here skip the merging when different Col2 contains record var nextDataCol2 = reflector.GetFormattedValue((nextData as RecordEntry).Data, "Col2"); object rowDataCol2 = reflector.GetFormattedValue(rowData, "Col2");
if (!compareData.Equals(data) || !nextDataCol2.Equals(rowDataCol2)) break;
nextRowIndex = i; }
if (previousRowIndex != -1 || nextRowIndex != -1) {
if (previousRowIndex != -1) range = new CoveredCellInfo(range.Left, range.Right, previousRowIndex, range.Bottom);
if (nextRowIndex != -1) range = new CoveredCellInfo(range.Left, range.Right, range.Top, nextRowIndex); return range; } return null; } |
Output screenshot:
Here we have prepared the sample based on your scenario. Please have a look at this and revert us if you have any concerns about this.
Regards,
Dhanasekar M.
If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.