我想在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;
也许问题出在这里。
答案 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;
}
}