Как объединить ячейку DataGridView в Winforms

У меня есть некоторые данные в сетке, которые в настоящее время отображаются следующим образом:

------------------
|Hd1| Value  |
------------------
|A  | A1     |
------------------
|A  | A2     |
------------------
|A  | A3     |
------------------
|A  | A4     |
------------------
|B  | B1     |
------------------
|B  | B2     |
------------------
|B  | B3     |
------------------
|B  | B4     |
------------------
|B  | B5     |
------------------
|C  | C1     |
------------------
|C  | C2     |
------------------

Я хочу сделать так:

|Hd | Value  |
------------------
|A  | A1     |
    ----------
|   | A2     |
    ----------
|   | A3     |
    ----------
|   | A4     |
------------------
|B  | B1     |
    ----------
|   | B2     |
    ----------
|   | B3     |
    ----------
|   | B4     |
    ----------
|   | B5     |
------------------
|C  | C1     |
    ----------
|   | C2     |
------------------

Есть ли способ, которым я могу объединить эти ячейки? Я пробовал во многом и Google, но не нашел подходящего способа. Если возможно показать эти данные другим способом, не используя datagridview, но результат будет таким, как я показал, что также решит мою проблему.

Ответ 1

Вы должны сначала найти повторяющиеся значения

Требуется два метода:

bool IsTheSameCellValue(int column, int row)
{
    DataGridViewCell cell1 = dataGridView1[column, row];
    DataGridViewCell cell2 = dataGridView1[column, row - 1];
    if (cell1.Value == null || cell2.Value == null)
    {
       return false;
    }
    return cell1.Value.ToString() == cell2.Value.ToString();
}

в случае, cellpainting:

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None;
    if (e.RowIndex < 1 || e.ColumnIndex < 0)
        return;
    if (IsTheSameCellValue(e.ColumnIndex, e.RowIndex))
    {
        e.AdvancedBorderStyle.Top = DataGridViewAdvancedCellBorderStyle.None;
    }
    else
    {
        e.AdvancedBorderStyle.Top = dataGridView1.AdvancedCellBorderStyle.Top;
    }  
}

теперь в форматировании ячейки:

if (e.RowIndex == 0)
    return;
if (IsTheSameCellValue(e.ColumnIndex, e.RowIndex))
{
    e.Value = "";
    e.FormattingApplied = true;
}

и в form_load:

dataGridView1.AutoGenerateColumns = false;

Image of DGV_Merge

Ответ 2

Элемент управления DataGridView не имеет связанных свойств или методов для слияния ячеек, но вы можете сделать то же самое с помощью пользовательской раскраски. Вы можете использовать DataGridView.CellPainting событие или переопределить метод Paint.

Кроме того, вам нужно будет переопределить DataGridView.CellClick, CellEnter, CellFormatting и другие методы, чтобы дать вашему DataGridView полнофункциональную функциональность. Например, при нажатии на ячейку вся объединенная ячейка (или группа ячеек, которые составляют объединенную ячейку) должна быть оформлена по индивидуальному заказу.

Здесь вы можете найти пример кода:

http://social.msdn.microsoft.com/forums/en-US/vbinterop/thread/5b659cbd-7d29-4da4-8b38-5d427c3762e2

http://forums.codeguru.com/showthread.php?415930-DataGridView-Merging-Cells

http://www.codeproject.com/Questions/152113/How-can-i-merge-DataGridView-Rows-Cells-with-Equal

Ответ 3

На asp.net есть несколько хороших ответов, но в winforms и для этого примера (объединение одних и тех же данных в столбцах) это не определено.

Вы можете использовать color.transparent, чтобы скрыть те же значения в datagridview. даже с помощью этого кода те же строки не удаляются и могут быть полезны для математических вычислений. даже вы можете определить, какие столбцы объединить по вашему желанию сортировать.

Таким образом, если конец "А" был "А4", а также "В" был "А4", это не было бы слиянием. Что часто более желательно. (Если вы не хотите этого, лучше используйте другие ответы)

MergeGridviewCells (DGV, new int [] {0,1});//Например, если вы хотите объединить данные первого столбца/затем 3-й столбец, а затем второй столбец, вы можете использовать новый int [] {0,2,1}

private void MergeGridviewCells(DataGridView DGV, int[] idx)
    {
        DataGridViewRow Prev = null;

        foreach (DataGridViewRow item in DGV.Rows)
        {
            if (Prev != null)
            {
                string firstCellText = string.Empty;
                string secondCellText = string.Empty;

                foreach (int i in idx)
                {                        
                    DataGridViewCell firstCell = Prev.Cells[i];
                    DataGridViewCell secondCell = item.Cells[i];

                    firstCellText = (firstCell != null && firstCell.Value != null ? firstCell.Value.ToString() : string.Empty);
                    secondCellText = (secondCell != null && secondCell.Value != null ? secondCell.Value.ToString() : string.Empty);

                    if (firstCellText == secondCellText)
                    {                           
                        secondCell.Style.ForeColor = Color.Transparent;
                    }
                    else
                    {
                        Prev = item;
                        break;
                    }
                }
            }
            else
            {
                Prev = item;
            }
        }
     }

Предварительный просмотр:

enter image description here