不知道大家又没有碰到这样的问题,在一个DataGridView中,一些列是绑定到数据源,一些列是没有绑定的,当对绑定的列进行排序的时候,未绑定的列数据就丢失。
代码如下
对绑定列排序,为绑定列值消失问题的解决办法:
设置VirtualMode=True,处理CellValueNeeded和CellValuePushed两个事件,要对未绑定的列保存起来,看看具体代码就清楚啦
这样处理之后再排序,未绑定的最后一列的值就不会消失。
代码如下
private void BindDataToGrid()
{
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = BuildTable();//set data source
if (!dataGridView1.Columns.Contains("ddl"))//add unbound column
{
DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
DataTable dtDev = PopulateData();
column.DataSource = dtDev;
column.ValueMember = dtDev.Columns[0].ColumnName;
column.DisplayMember = dtDev.Columns[1].ColumnName;
column.ReadOnly = false;
column.Name = "ddl";
column.HeaderText = "choose one";
dataGridView1.Columns.Add(column);
}
}
private DataTable PopulateData()//for ComboBoxColumn
{
DataTable dtData = new DataTable();
dtData.Columns.Add("id", Type.GetType("System.String"));
dtData.Columns.Add("name", Type.GetType("System.String"));
object[] p1 = { "001","agan" };
object[] p2 = { "002","asca" };
object[] p3 = { "004", "lt" };
dtData.Rows.Add(p1);
dtData.Rows.Add(p2);
dtData.Rows.Add(p3);
return dtData;
}
private DataTable BuildTable()//build data table
{
DataTable dtData = new DataTable();
dtData.Columns.Add("Select", Type.GetType("System.Boolean"));
dtData.Columns.Add("Col1", Type.GetType("System.String"));
dtData.Columns.Add("Col2", Type.GetType("System.Int32"));
dtData.Columns.Add("Col3", Type.GetType("System.String"));
object[] row1 = { true, "1", 2, "3" };
object[] row2 = { false, "4", 5, "6"};
dtData.Rows.Add(row1);
dtData.Rows.Add(row2);
return dtData;
}
{
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = BuildTable();//set data source
if (!dataGridView1.Columns.Contains("ddl"))//add unbound column
{
DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
DataTable dtDev = PopulateData();
column.DataSource = dtDev;
column.ValueMember = dtDev.Columns[0].ColumnName;
column.DisplayMember = dtDev.Columns[1].ColumnName;
column.ReadOnly = false;
column.Name = "ddl";
column.HeaderText = "choose one";
dataGridView1.Columns.Add(column);
}
}
private DataTable PopulateData()//for ComboBoxColumn
{
DataTable dtData = new DataTable();
dtData.Columns.Add("id", Type.GetType("System.String"));
dtData.Columns.Add("name", Type.GetType("System.String"));
object[] p1 = { "001","agan" };
object[] p2 = { "002","asca" };
object[] p3 = { "004", "lt" };
dtData.Rows.Add(p1);
dtData.Rows.Add(p2);
dtData.Rows.Add(p3);
return dtData;
}
private DataTable BuildTable()//build data table
{
DataTable dtData = new DataTable();
dtData.Columns.Add("Select", Type.GetType("System.Boolean"));
dtData.Columns.Add("Col1", Type.GetType("System.String"));
dtData.Columns.Add("Col2", Type.GetType("System.Int32"));
dtData.Columns.Add("Col3", Type.GetType("System.String"));
object[] row1 = { true, "1", 2, "3" };
object[] row2 = { false, "4", 5, "6"};
dtData.Rows.Add(row1);
dtData.Rows.Add(row2);
return dtData;
}
运行出来的结果是这样的,前面4列是绑定到数据源的,最后一列是未绑定列,是一个DataGridViewComboCheckBoxColumn,先选中一些值
点击第二列Col1排序,最后一列前面选择的值就消失啦
这问题困扰我很久啦,网上也没有找到比较好的解决办法,还望大家多多指教,谢谢。
如果是绑定这些列,然后设置sortmode就不会有这样的问题,下面是改变的代码
private void BindDataToGrid()
{
dataGridView1.AutoGenerateColumns = false;
AddColumns();
dataGridView1.DataSource = BuildTable();//set data source
}
private void AddColumns()//add all columns
{
DataGridViewCell cell;
cell = new DataGridViewCheckBoxCell();
DataGridViewColumn col = new DataGridViewColumn(cell);
col.Name = "select";
col.HeaderText = "select";
col.DataPropertyName = "select";
col.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col);
cell = new DataGridViewTextBoxCell();
DataGridViewColumn col1 = new DataGridViewColumn(cell);
col1.Name = "col1";
col1.HeaderText = "col1";
col1.DataPropertyName = "col1";
col1.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col1);
DataGridViewColumn col2 = new DataGridViewColumn(cell);
col2.Name = "col2";
col2.HeaderText = "col2";
col2.DataPropertyName = "col2";
col2.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col2);
DataGridViewColumn col3 = new DataGridViewColumn(cell);
col3.Name = "col3";
col3.HeaderText = "col3";
col3.DataPropertyName = "col3";
col3.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col3);
//cell = new DataGridViewComboBoxCell();
DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
DataTable dtDev = PopulateData();
column.DataSource = dtDev;
column.ValueMember = dtDev.Columns[0].ColumnName;
column.DisplayMember = dtDev.Columns[1].ColumnName;
column.ReadOnly = false;
column.Name = "ddl";
column.HeaderText = "choose one";
column.DataPropertyName = "col4";
column.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(column);
}
private DataTable PopulateData()//for ComboBoxColumn
{
DataTable dtData = new DataTable();
dtData.Columns.Add("id", Type.GetType("System.String"));
dtData.Columns.Add("name", Type.GetType("System.String"));
object[] p1 = { "001","agan" };
object[] p2 = { "002","asca" };
object[] p3 = { "004", "lt" };
dtData.Rows.Add(p1);
dtData.Rows.Add(p2);
dtData.Rows.Add(p3);
return dtData;
}
private DataTable BuildTable()//build data table
{
DataTable dtData = new DataTable();
dtData.Columns.Add("Select", Type.GetType("System.Boolean"));
dtData.Columns.Add("Col1", Type.GetType("System.String"));
dtData.Columns.Add("Col2", Type.GetType("System.Int32"));
dtData.Columns.Add("Col3", Type.GetType("System.String"));
dtData.Columns.Add("Col4", Type.GetType("System.String"));
object[] row1 = { true, "1", 2, "3","" };
object[] row2 = { false, "4", 5, "6",""};
dtData.Rows.Add(row1);
dtData.Rows.Add(row2);
return dtData;
}
上面sortmode都是设置成自动排序,关于这属性详细设置,请参考msdn。 {
dataGridView1.AutoGenerateColumns = false;
AddColumns();
dataGridView1.DataSource = BuildTable();//set data source
}
private void AddColumns()//add all columns
{
DataGridViewCell cell;
cell = new DataGridViewCheckBoxCell();
DataGridViewColumn col = new DataGridViewColumn(cell);
col.Name = "select";
col.HeaderText = "select";
col.DataPropertyName = "select";
col.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col);
cell = new DataGridViewTextBoxCell();
DataGridViewColumn col1 = new DataGridViewColumn(cell);
col1.Name = "col1";
col1.HeaderText = "col1";
col1.DataPropertyName = "col1";
col1.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col1);
DataGridViewColumn col2 = new DataGridViewColumn(cell);
col2.Name = "col2";
col2.HeaderText = "col2";
col2.DataPropertyName = "col2";
col2.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col2);
DataGridViewColumn col3 = new DataGridViewColumn(cell);
col3.Name = "col3";
col3.HeaderText = "col3";
col3.DataPropertyName = "col3";
col3.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(col3);
//cell = new DataGridViewComboBoxCell();
DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
DataTable dtDev = PopulateData();
column.DataSource = dtDev;
column.ValueMember = dtDev.Columns[0].ColumnName;
column.DisplayMember = dtDev.Columns[1].ColumnName;
column.ReadOnly = false;
column.Name = "ddl";
column.HeaderText = "choose one";
column.DataPropertyName = "col4";
column.SortMode = DataGridViewColumnSortMode.Automatic;//set sort mode
dataGridView1.Columns.Add(column);
}
private DataTable PopulateData()//for ComboBoxColumn
{
DataTable dtData = new DataTable();
dtData.Columns.Add("id", Type.GetType("System.String"));
dtData.Columns.Add("name", Type.GetType("System.String"));
object[] p1 = { "001","agan" };
object[] p2 = { "002","asca" };
object[] p3 = { "004", "lt" };
dtData.Rows.Add(p1);
dtData.Rows.Add(p2);
dtData.Rows.Add(p3);
return dtData;
}
private DataTable BuildTable()//build data table
{
DataTable dtData = new DataTable();
dtData.Columns.Add("Select", Type.GetType("System.Boolean"));
dtData.Columns.Add("Col1", Type.GetType("System.String"));
dtData.Columns.Add("Col2", Type.GetType("System.Int32"));
dtData.Columns.Add("Col3", Type.GetType("System.String"));
dtData.Columns.Add("Col4", Type.GetType("System.String"));
object[] row1 = { true, "1", 2, "3","" };
object[] row2 = { false, "4", 5, "6",""};
dtData.Rows.Add(row1);
dtData.Rows.Add(row2);
return dtData;
}
对绑定列排序,为绑定列值消失问题的解决办法:
设置VirtualMode=True,处理CellValueNeeded和CellValuePushed两个事件,要对未绑定的列保存起来,看看具体代码就清楚啦
private void Form2_Load(object sender, EventArgs e)
{ this.dataGridView1.VirtualMode = true;
this.dataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);
this.dataGridView1.CellValuePushed += new DataGridViewCellValueEventHandler(dataGridView1_CellValuePushed);
}
private void dataGridView1_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
{
currentID = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
hshData[currentID] = e.Value;
}
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
if (e.ColumnIndex == 4)//unbound column
{
currentID = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if(hshData[currentID]!=null)
e.Value = hshData[currentID].ToString();
}
}
currentID标识当前编辑行的ID,hshData保存当前行未绑定列的值和行标识的映射。{ this.dataGridView1.VirtualMode = true;
this.dataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);
this.dataGridView1.CellValuePushed += new DataGridViewCellValueEventHandler(dataGridView1_CellValuePushed);
}
private void dataGridView1_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
{
currentID = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
hshData[currentID] = e.Value;
}
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
if (e.ColumnIndex == 4)//unbound column
{
currentID = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if(hshData[currentID]!=null)
e.Value = hshData[currentID].ToString();
}
}
这样处理之后再排序,未绑定的最后一列的值就不会消失。