dataGridView过滤后如何保持行号不变

时间:2016-02-22 10:02:54

标签: c# .net winforms datagridview

我有一个带有8行的datagridview,我过滤了第3,4和5行中包含的值。这意味着在我过滤后我希望在行标题中看到行3,4,5。如果我将rowheader值设置为常量,也许可以以某种方式完成?

我目前的过滤方法是:

BindingSource bs = (BindingSource)Dgv.DataSource;
bs.Filter = string.Format(...);
Dgv.DataSource = bs;

我目前的行编号方法是:

private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    using (SolidBrush b = new 
    SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.ForeColor))
    {
        e.Graphics.DrawString((e.RowIndex + 1).ToString(), e.InheritedRowStyle.Font, b,
        e.RowBounds.Location.X + 10,
        e.RowBounds.Location.Y + 4);
    }
}

这绘制了行列表,但每当我进行过滤时,它们都会从头开始编号(1,2,3 ......)。

如果我以这种方式设置行号:

for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
   dgv1.Rows[i].HeaderCell.Value = String.Format("{0}", i + 1);
}

然后在过滤后我完全丢失了行标题中的值。所以我想在第一次装载表时给行列表一个恒定值?

1 个答案:

答案 0 :(得分:1)

数字会在过滤后重新开始,因为e.RowIndex将始终贯穿DataGridView.Rows的计数 - 这会在过滤时发生变化。

假设您的BindingSource.DataSourceDataTable,您可以通过从未过滤的来源获取该项目的索引来实现您的目标:

private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
    var rowItem = (DataRowView)this.dataGridView1.Rows[e.RowIndex].DataBoundItem;
    int index = ((this.dataGridView1.DataSource as BindingSource).DataSource as DataTable).Rows.IndexOf(rowItem.Row);

    using (SolidBrush b = new SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.ForeColor))
    {
        e.Graphics.DrawString((index + 1).ToString(), e.InheritedRowStyle.Font, b,
        e.RowBounds.Location.X + 10,
        e.RowBounds.Location.Y + 4);
    }
}

如果基础源是IBindingListView的其他实现,那么类似地,您需要转换行项并在源集合中找到它的索引:

var rowItem = (MyObject)this.dataGridView1.Rows[e.RowIndex].DataBoundItem;
int index = ((this.dataGridView1.DataSource as BindingSource).IndexOf(rowItem);

这个想法是:您的物品将根据其在主要集合中的顺序进行编号。应用过滤器时,集合视图会更改,但集合本身仍包含所有对象,因此顺序 - 和编号 - 保持不变。