greenshoots
asked on
Sorting problems in GridView and DetailsView
I use a datatable to do some sorting for a GridView
dtSort.DefaultView.Sort = e.SortExpression + (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
Then I save the dtSort in ViewState["DataTable2"].
And then use it with the GridView. And it get sorted. Sorting works great in the GridView.
But when I set this same sorted datatable (ViewState["DataTable2"]) as DetailsViews datasource it looks like the sortorder not comes here.
Then the PageID is not the same as the rowindex in the GridView. I got the rowindex from the DataTable and not from the GridView so it should work in both GridView and DetailsView objects?
What do I miss? Looks like it works different in GridView and DetailsView?
dtSort.DefaultView.Sort = e.SortExpression + (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
Then I save the dtSort in ViewState["DataTable2"].
And then use it with the GridView. And it get sorted. Sorting works great in the GridView.
But when I set this same sorted datatable (ViewState["DataTable2"]) as DetailsViews datasource it looks like the sortorder not comes here.
Then the PageID is not the same as the rowindex in the GridView. I got the rowindex from the DataTable and not from the GridView so it should work in both GridView and DetailsView objects?
What do I miss? Looks like it works different in GridView and DetailsView?
ASKER
SelectParameters you use in DataSource?
My DataSourse is a DataTable and I use no SQL. I also assign the DataTable with code not in the aspx.
Can I then use SelectParameters?
My DataSourse is a DataTable and I use no SQL. I also assign the DataTable with code not in the aspx.
Can I then use SelectParameters?
ASKER
I try to use my DataTable with ObjectDataSource maybe it works... :)
ASKER
I think I have got it:
public DataTable GetDataTableForObjectSourc e()
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string)),
new DataColumn("Country",typeo f(string)) });
dt.Rows.Add(1, "John Hammond", "United States");
dt.Rows.Add(2, "Mudassar Khan", "India");
dt.Rows.Add(3, "Suzanne Mathews", "France");
dt.Rows.Add(4, "Robert Schidner", "Russia");
if (ViewState["DataTable"] != null)
{
dt = (DataTable)ViewState["Data Table"];
}
ViewState["DataTable"] = dt;
return dt;
}
private void PopulateDetailsView()
{
try
{
var objectDataSource1 =
new ObjectDataSource(this.GetT ype().Asse mblyQualif iedName, "GetDataTableForObjectSour ce") { ID = "ObjectDataSource1" };
ControlParameter cp = new ControlParameter();
cp.ControlID = "GridView2";
cp.Name = "Id";
Controls.Add(objectDataSou rce1);
GridView2.DataSourceID = "ObjectDataSource1";
GridView2.DataBind();
DetailsView1.DataSourceID = "ObjectDataSource1";
DetailsView1.DataBind();
}
catch (Exception ex_)
{
Debug.WriteLine(ex_.ToStri ng());
log.Info(ex_.ToString());
}
}
public DataTable GetDataTableForObjectSourc
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string)),
new DataColumn("Country",typeo
dt.Rows.Add(1, "John Hammond", "United States");
dt.Rows.Add(2, "Mudassar Khan", "India");
dt.Rows.Add(3, "Suzanne Mathews", "France");
dt.Rows.Add(4, "Robert Schidner", "Russia");
if (ViewState["DataTable"] != null)
{
dt = (DataTable)ViewState["Data
}
ViewState["DataTable"] = dt;
return dt;
}
private void PopulateDetailsView()
{
try
{
var objectDataSource1 =
new ObjectDataSource(this.GetT
ControlParameter cp = new ControlParameter();
cp.ControlID = "GridView2";
cp.Name = "Id";
Controls.Add(objectDataSou
GridView2.DataSourceID = "ObjectDataSource1";
GridView2.DataBind();
DetailsView1.DataSourceID = "ObjectDataSource1";
DetailsView1.DataBind();
}
catch (Exception ex_)
{
Debug.WriteLine(ex_.ToStri
log.Info(ex_.ToString());
}
}
ASKER
But when I add DataKeyNames="PageID" it does not work. Looks like it must be an existing column in the DataTable.
Yes, it must be an existing column. You mentioned PageID in your original question so I assumed that was your key column but if it is "Id" then use that instead.
ASKER
I don't understand how to take advantage of that.
Let's say I try to change the current PageID for the DetailsView when I select the row in the GridView.
protected void GridView1_SelectedIndexCha nged(objec t sender, EventArgs e) {
GridViewRow gwr = GridView1.Rows[GridView1.S electedInd ex];
int Id_Index = GetColumnIndexByName(GridV iew1.Heade rRow, "Id");
string Id = Convert.ToString(gwr.Cells [Id_Index] .Text);
}
And then I need to check where this ID is in DetailsView and then get the corresponding PageID / RowIndex or something and then set the PageID for the DetailsView?
Or is there something smart and easier I now can do with this mapping.
Let's say I try to change the current PageID for the DetailsView when I select the row in the GridView.
protected void GridView1_SelectedIndexCha
GridViewRow gwr = GridView1.Rows[GridView1.S
int Id_Index = GetColumnIndexByName(GridV
string Id = Convert.ToString(gwr.Cells
}
And then I need to check where this ID is in DetailsView and then get the corresponding PageID / RowIndex or something and then set the PageID for the DetailsView?
Or is there something smart and easier I now can do with this mapping.
ASKER
Or is now my PageID in the DetailsView the same as my Controllparameter?
ControlParameter cp = new ControlParameter();
cp.ControlID = "GridView2";
cp.Name = "Id";
I should maybe here set ControlID="DetailsView1" according to what was said?
ControlParameter cp = new ControlParameter();
cp.ControlID = "GridView2";
cp.Name = "Id";
I should maybe here set ControlID="DetailsView1" according to what was said?
ASKER
Or could I use more than one Controllparameter in the Objectdatasource?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you so much for your help.
Glad to hear you found the answer. My apologies for the late response - I wasn't at my normal desk over the weekend so I didn't have a chance to test and respond before now.
Imagine the GridView is just like an Excel spreadsheet, where the row number never changes, even if the data is sorted differently. At a certain point, the IDs might just COINCIDENTALLY line up with the row numbers, but again, that's coincidental. At any moment, the data could be sorted differently by code or by the user, and the IDs would not match up anymore:
So what you can do here is first specify DataKeyNames in your GridView and DetailsView, like this:
https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.gridview.datakeynames?view=netframework-4.8
<asp:GridView ID="YourGridView" DataKeyNames="PageID" ...>
...
</asp:GridView>
Then in your DetailsView, use SelectParameters to map to the GridView PageID:
<SelectParameters>
<asp:ControlParameter ControlID="YourGridView" Name="PageID" />
</SelectParameters>
That should ensure that the DetailsView is linked to the PageID key of your GridView rather than trying to link on the unreliable row index.