加载表格数据的时候发现原来的rows没有清除,再次加载的时候就会重复加一遍
绑定数据源写法:
DataTable dataGridView = null;
先定义一个datatable,把columns绑定进去,再用它存数据
columns的写法:
在循环里:
DataColumn dataColumn = new DataColumn(item.DataField);
dataGridView.Columns.Add(dataColumn);
同时在这个循环里也把datagridview1,也就是画面上这个真正的表格绑定了列,只有这个才会显示出来,dataTable那个列只是用来存数据源的:
this.dataGridView1.Columns.Add(textColumn);
这个textColumn是一个DataGridViewTextBoxColumn类型的对象,里面的属性设好就可以了;
完整代码:
private void LoadColumns()
{
this.dataGridView = new DataTable();
this.dataGridView1.Columns.Clear();
if (_columns != null && _columns.Count() > 0)
{
int intColumnsCount = _columns.Count();
if (_isShowCheckBox)
{
intColumnsCount++;
}
for (int i = 0; i < intColumnsCount; i++)
{
if (i == 0 && _isShowCheckBox)
{
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn());
}
else
{
var item = _columns[i - (_isShowCheckBox ? 1 : 0)];
DataGridViewCellStyle gridViewStyle = dataGridView1.ColumnHeadersDefaultCellStyle;
gridViewStyle.Font = _headFont;
gridViewStyle.ForeColor = _headTextColor;
gridViewStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn();
textColumn.Name = "dgvColumns_" + i;
textColumn.HeaderText = item.HeadText;
textColumn.DataPropertyName = item.DataField;
textColumn.DefaultCellStyle = gridViewStyle;
textColumn.SortMode = DataGridViewColumnSortMode.NotSortable;
DataColumn dataColumn = new DataColumn(item.DataField);
dataGridView.Columns.Add(dataColumn);
this.dataGridView1.Columns.Add(textColumn);
}
}
}
}
这里面写了个showcheckbox,是用来显示勾选框的,如果没有需要可以不写
下面开始绑定数据源,直接贴代码吧
public void ReloadSource()
{
if (DesignMode)
{
return;
}
dataGridView.Clear();
Rows = new List<IDataGridViewRow>();
if (_columns == null || _columns.Count <= 0)
return;
if (_dataSource != null)
{
int intIndex = 0;
_selectRow = null;
int intSourceCount = 0;
if (_dataSource is DataTable)
intSourceCount = (_dataSource as DataTable).Rows.Count;
else if (typeof(IList).IsAssignableFrom(_dataSource.GetType()))
intSourceCount = (_dataSource as IList).Count;
if (intIndex < intSourceCount)
{
for (int i = intIndex; i < intSourceCount; i++)
{
DataRow dataRow = dataGridView.NewRow();
object sourceRow = null;
if (_dataSource is DataTable)
{
sourceRow = (_dataSource as DataTable).Rows[i];
}
else if (_dataSource is List<UCDataGridViewRowClass>)
{
sourceRow = ((List<UCDataGridViewRowClass>)_dataSource)[i].DataSource;
}
else
{
sourceRow = (_dataSource as IList)[i];
}
Type tp = sourceRow.GetType();
MemberInfo[] s = tp.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
foreach(MemberInfo item in s)
{
PropertyInfo p = tp.GetProperty(item.Name);
if(p != null)
{
object temp = p.GetValue(sourceRow, null);
dataRow[item.Name] = temp;
}
}
dataGridView.Rows.Add(dataRow);
}
this.dataGridView1.DataSource = dataGridView;
for (int i = intIndex; i < intSourceCount; i++)
{
DataGridViewCellStyle rowStyle = new DataGridViewCellStyle();
rowStyle.BackColor = BackColor;
rowStyle.ForeColor = ForeColor;
rowStyle.Font = new Font("微软雅黑", 12);
rowStyle.SelectionBackColor = Color.FromArgb(60, 79, 117);
DataGridViewRow textRow = dataGridView1.Rows[i];
textRow.DefaultCellStyle = rowStyle;
textRow.Height = _rowHeight;
}
dataGridView1.ClearSelection();
}
}
else
{
dataGridView.Clear();
}
//panRow.AutoScrollPosition = newPoint;
}
思路就是用一个反射把每一行的所有列放进来,我这个是自定义控件,所以判断了一下传进来的datasource类型,重点来了,就是这段:
this.dataGridView1.DataSource = dataGridView;
这句话是把整个datasource放进来,然后datagridview1就会产生自身的rows,也就是datagridview1.Rows,事后还要处理
一开头的时候我们会把datatable清掉,这样datagridview1引用的数据源就没有了,对应的rows也应该就没有了
但是代码就是门玄学,我们发现每次重新加载表格的时候,他都能清掉rows,唯独某一次,大概是开了一个新线程,他就清不掉了,datagridview.Clear()这句话走完了之后,datagridview1的rows仍然还是有值的
我实在不知道为什么,于是就想着把datagridview1的rows直接清掉,然后报错:不能清除此列表
于是百度了一下,把这个rows循环然后removeAt,就可以清掉了
while (this.dataGridView1.Rows.Count != 0)
{
this.dataGridView1.Rows.RemoveAt(0);
}
我终于明白我为什么技术不好了,我每次遇到一个这种比较棘手的问题,都是想办法解决,一个办法不行换另一种办法,但是我没法找到它的原理,它为什么不行,又为什么行,这个我不知道怎么去找,所以我的csdn也没人看,因为什么都没讲,只告诉你用这个方法试一试,好用就好用,不好用那就换别的办法,我还是得研究研究去,它到底为什么最后一次不clear呢?
over