在使用Datagridview时,当重新对DataSoruce 属性赋值时,往往列顺序就会改变为DataSource属性的值的排序顺序。这样就会破坏我们的设计,违背我们原来的意图。那有什么方法可以列序按照我们的想法来排列呢? 方法有两种: 1、让DataSource属性的新值的Columns按照我们要的顺序排序。 2、在给DataSource属性赋值之后,对列(Column)的DataPropertyName属性绑定一个数据字段, 3、改写DataGridView。 下面我们对以上三种方法,进行分析: 第一种方法实现简单,但这样做如果数据结构(或需求)变化时,要修改的地方比较多,而且不便于设计时的所见即所得,更不便于维护,所以我不采用它。 第二种方法,好是很好,但当Column包含有按钮列等其它非文本列时一样会进行重新排序,所以这种方法也不能满足我们的需求。 最后我只有采用第三种方法:改写DataGridView,我们增加一个新的DataSourceNew属性,在它的set访问器,里增加两个方法。一个是保存列序号,它在赋值之前运行,一个是恢复列号,它是赋值之后运行,这样就可以达到我们的需求了。另外为了保存我们的列号,还增加了一个私有的字段_displayIndex(Hashtable类型). 代码如下:
[ToolboxBitmap(typeof(DataGridView))]
public partial class dgvHasRowNum : DataGridView
{
public dgvHasRowNum()
{
InitializeComponent();
this.RowPostPaint += new DataGridViewRowPostPaintEventHandler(dgvHasRowNum_RowPostPaint);
}
void dgvHasRowNum_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
Rectangle rect = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y,
dgv.RowHeadersWidth - 4, e.RowBounds.Height);
TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
dgv.RowHeadersDefaultCellStyle.Font,
rect,
dgv.RowHeadersDefaultCellStyle.ForeColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
}
/// <summary>
/// 重写DataSource属性,让它在改变之前保存好列序,然后重新
/// </summary>
public object DataSourceNew
{
get
{
return this.DataSource;
}
set
{
bakupColumnDisplayIndex();
this.DataSource = value;
resortColumnDisplayIndex();
}
}
private void bakupColumnDisplayIndex()
{
this._displayIndex.Clear();
foreach (DataGridViewColumn dc in this.Columns)
{
this._displayIndex.Add(dc.Name, dc.DisplayIndex);
}
}
private void resortColumnDisplayIndex()
{
for (int i = 0; i < this.Columns.Count; i++)
{
this.Columns[i].DisplayIndex = (int)_displayIndex[this.Columns[i].Name];
}
}
private Hashtable _displayIndex = new Hashtable();
}