datagridview:合并具有相同值的多行

时间:2018-08-01 09:47:51

标签: c# datagridview

我想在datagridview中实现具有相同值的组合多行,这是通用的,使用BindlingList。 但是,当我使用它时,它会显示错误:单元格的格式化值类型错误。 有什么建议吗?谢谢!

代码如下:

public partial class PetrelDataGridView<T> : DataGridView
    where T : IRowInit, new()
{
    public PetrelDataGridView()
    {

        InitializeComponent();
        //CellValidating += OnCellValidating;
        DataError += MasterDataGridView_DataError;
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
    protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs args)
    {
        // Call home to base
        base.OnCellFormatting(args);

        // First row always displays
        if (args.RowIndex == 0)
            return;

        if (IsRepeatedCellValue(args.RowIndex, args.ColumnIndex))
        {
            args.Value = string.Empty;
            args.FormattingApplied = true;
        }
    }

    private bool IsRepeatedCellValue(int rowIndex, int colIndex)
    {
        DataGridViewCell currCell = Rows[rowIndex].Cells[colIndex];
        DataGridViewCell prevCell = Rows[rowIndex - 1].Cells[colIndex];

        if ((currCell.Value == prevCell.Value) ||
           (currCell.Value != null && prevCell.Value != null &&
           currCell.Value.ToString() == prevCell.Value.ToString())
           )
        {
            if (IsSameRowUID(rowIndex, colIndex))
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }
    }

    protected override void OnCellPainting(DataGridViewCellPaintingEventArgs args)
    {
        base.OnCellPainting(args);
        args.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None;
        // Ignore column and row headers and first row
        if (args.RowIndex < 1 || args.ColumnIndex < 0)
            return;
        if (IsRepeatedCellValue(args.RowIndex, args.ColumnIndex))
        {
            args.AdvancedBorderStyle.Top = DataGridViewAdvancedCellBorderStyle.None;
        }
        else
        {
            args.AdvancedBorderStyle.Top = AdvancedCellBorderStyle.Top;
        }

    }

    private bool IsSameRowUID(int rowIndex, int colIndex)
    {
        //BindingList<T> bdList = (BindingList<T>)(DataSource.DataSource);
        T t1 = (T)Rows[rowIndex].DataBoundItem;
        T t2 = (T)Rows[rowIndex-1].DataBoundItem;
        if (t1.GetRowUID() == t2.GetRowUID())
            return true;
        else
            return false;
    }}

如您所见,我实现了DataError事件以捕获异常,但是我仍然找不到问题所在。

错误消息:

  

格式化,显示

     

单元格的格式化值类型错误。

嗨,我评论了复选框列代码后,它运行良好:

 //add checkbox column
        DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
        checkColumn.Name = "X";
        checkColumn.HeaderText = "";
        checkColumn.Width = 50;
        checkColumn.ReadOnly = false;
        checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values
        _dataGridView.Columns.Add(checkColumn);


        //add checkbox at (0,-1)
        _dgrCheckBox = new CheckBox();
        _dgrCheckBox.Size = new Size(18, 18);
        //Get the column header cell bounds
        Rectangle rect =
            this._dataGridView.GetCellDisplayRectangle(0, -1, true);

        rect.Offset(5, 1);

        //Change the location of the CheckBox to make it stay on the header
        _dgrCheckBox.Location = rect.Location;
        _dgrCheckBox.CheckedChanged += new EventHandler(ckBox_CheckedChanged);

        //Add the CheckBox into the DataGridView
        this._dataGridView.Controls.Add(_dgrCheckBox);

        _dataGridView.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;

也许问题出在这里。

1 个答案:

答案 0 :(得分:0)

取消列0(复选框列)合并后,效果很好:

 protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs e)
    {
        // Call home to base
        //base.OnCellFormatting(e);

        // First row always displays
        if (e.RowIndex == 0)
            return;

        if (IsRepeatedCellValue(e.RowIndex, e.ColumnIndex))
        {
            if (e.ColumnIndex == 0)
                return;
            e.Value = string.Empty;
            e.FormattingApplied = true;
        }
    }