Hi experts,
I'm having a datasource that consists of customer data. To make it easy, assume there is one row per customer, inluding his name, address, last order, status and much more.
As there are quite a lot of fields, I need to provide my users with a grid view that supports customizable "layouts": The first four columns of this grid view are always the same: (1) checkbox, (2) image, (3) lastname, (4) firstname. I implemented these columns as TemplateFields during design time.
All other columns (column 5 - coIumn x) can be configured freely by my users. In other words: I let them choose (a) which columns they want to see and (b) in which order they want to see these columns.
By the way: the whole grid view is just for viewing and selection purposes, so there is no edit or delete functionality implemented.
So, this is what I'm doing if a user trys to change the gridview layout:
private void ChangePoolLayout()
{
//1. Clear all custom columns (the first four columns must stay)
for (int i = (gridView.Columns.Count - 1); i > 3; i--)
{
gridView.Columns.RemoveAt(
i);
}
//2. Add custom columns in required sort order
foreach (...)
{
//Create a new bound field
BoundField newField = new BoundField();
[...]
//Add field to the columns collection of the grid view
gridView.Columns.Add(newFi
eld);
}
//3. Rebind grid view
gridView.DataSource = myDataSource;
gridView.DataBind();
}
HERE IS MY PROBLEM:
When I'm doing this the second time (second postback), the first four columns are still existent (showing the correct header captions), but they lost their ItemTemplates. Which means: the first four columns are suddenly *empty*.
I'm guesing this is a matter of the ViewState (which is set to true for the grid view) and/or dynamic control generation. So I tried to save the first columns to teh session on the very first time the page is called:
void Page_Init(object sender, EventArgs e)
{
//Save first four columns to the session
List<TemplateField> StandardColumns = new List<TemplateField>();
if (Session["StdColumns"] == null)
{
foreach (TemplateField stdField in gridView.Columns)
{
StandardColumns.Add(stdFie
ld);
}
Session["StdColumns"] = StandardColumns;
}
}
and then modified my procedure like this:
private void ChangePoolLayout()
{
//1. Restore original layout (= 4 standard columns)
//Clear ALL current columns
gridView.Columns.Clear();
//Read original layout from the session
List<TemplateField> StandardColumns = (List<TemplateField>)Sessi
on["StdCol
umns"];
//Rebuild original layout
foreach (TemplateField stdField in StandardColumns)
{
gridView.Columns.Add(stdFi
eld);
}
//2. Add custom columns in required sort order
foreach (...)
{
//Create a new bound field
BoundField newField = new BoundField();
[...]
//Add field to the columns collection of the grid view
gridView.Columns.Add(newFi
eld);
}
//3. Rebind grid view
gridView.DataSource = myDataSource;
gridView.DataBind();
}
But here I'm running into "InvalidOperationException
" on the DataBind(), saying that databinding methods like Eval(), XPath() and Bind() can only be used in the context of a databound control. To be honest, that does not give me any clue, because I checked with the debugger that the datasource is correct and even the grid columns are exactly as I expect them at this moment (including the ItemTemplates for the first four columns).
Well, I hope this was not too confusing AND that anybody can really help me out here.
Thanks so much!