How to Sort in GridView - asp.net

Here is my GV.
<asp:GridView ID="Grid1" runat="server" AutoGenerateColumns="false"
AllowPaging="True" OnPageIndexChanging="Grid1_PageIndexChanging">
<Columns>
<asp:BoundField DataField="One" HeaderText="One" />
<asp:BoundField DataField="Two" HeaderText="Two" />
<asp:BoundField DataField="Three" HeaderText="Three" />
</Columns>
</asp:GridView>
I'm populating the GV with a Stored Procedure.
table = PublicClass.Sql_GetTable("usp_GetReportGridView", "NCIU");
Grid1.DataSource = table;
Grid1.DataBind();
How can I sort using the column headers?

First you need to enable AllowSorting property to be true. When enabled, the grid renders LinkButton controls in the header for each column. When the button is clicked, the grid's SortCommand event is thrown. It's up to the you to handle this event in the code. Because DataGrid always displays the data in the same order it occurs in the data source, the typical logic sorts the data source, and then rebinds the data to the grid.look at code below:
//AllowSorting="True"
//OnSorting="GridView2_Sorting"
//SortExpression="name"
protected void GridView2_Sorting(object sender, GridViewSortEventArgs e)
{
//to check whether to display in ascending order or descending order
if (e.SortExpression.Trim() == this.SortField)
this.SortDirection = (this.SortDirection == "D" ? "A" : "D");
else
this.SortDirection = "A";
this.SortField = e.SortExpression;
TempTable();
}

Related

ASP.NET Gridview Selected Index Changed not firing

This has been asked quite a few times, but still.
In GridView is defined event OnSelectedIndexChanged. My expectation is, that if I click on a row in gridview, the event will be fired. I managed to do the same with image buttons, but I want the entire row to be clickable.
<asp:GridView runat="server" ID="gameGrid" PageSize="20" PagerSettings-Mode="NextPreviousFirstLast"
OnRowDataBound="GameGrid_RowDataBound" OnPageIndexChanging="GameGrid_PageIndexChanging"
AutoGenerateColumns="false" CssClass="table table-hover table-striped" AllowPaging="True"
AllowSorting="True" ShowHeaderWhenEmpty="True" OnSelectedIndexChanged="gameGrid_SelectedIndexChanged">
<Columns>
<asp:BoundField HeaderText="Game Id" DataField="ID_Game" SortExpression="ID_Game" />
<asp:BoundField HeaderText="Player" DataField="Email" SortExpression="Email" />
<asp:BoundField HeaderText="Finshed" SortExpression="Finished" />
<asp:BoundField HeaderText="Started At" SortExpression="CreateDate" />
<asp:BoundField HeaderText="Last Updated At" SortExpression="LastUpdate" />
</Columns>
</asp:GridView>
I was assuming that if I define an EventHandler in CodeBehind, it will be fired.
protected void gameGrid_SelectedIndexChanged(object sender, EventArgs e)
{
int i = 0;
}
Why is this event not firing?
I would like to redirect the user on a different page with an ID parameter in URL. Should I do something different?
First, set the AutoGenerateSelectButton property to true in the GridView. This will generate a LinkButton. Now in the RowDataBound event do the following.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//find the select button in the row (in this case the first control in the first cell)
LinkButton lb = e.Row.Cells[0].Controls[0] as LinkButton;
//hide the button, but it still needs to be on the page
lb.Attributes.Add("style", "display:none");
//add the click event to the gridview row
e.Row.Attributes.Add("onclick", Page.ClientScript.GetPostBackClientHyperlink((GridView)sender, "Select$" + e.Row.RowIndex));
}
}
You could add the OnClick event to the row without showing the SelectButton, but then you would to turn off EnableEventValidation as seen here How to create a gridview row clickable?

Getting the DataKey Value in ASP.NET GridView on Button command event

Gridview is configured:
<asp:GridView ID="gvApptList" runat="server" CssClass="fullwidth" AutoGenerateColumns="False" DataKeyNames="AppointmentID">
<Columns>
<asp:BoundField DataField="Designer" HeaderText="Designer" SortExpression="Designer" />
<asp:BoundField DataField="AppointmentDTM" HeaderText="Appointment Date" SortExpression="AppointmentDTM" DataFormatString="{0:MM-dd-yyyy hh:mm tt}" />
<asp:BoundField DataField="Status" HeaderText="Status" SortExpression="Status" />
<asp:BoundField DataField="Disposition" HeaderText="Disposition" SortExpression="Disposition" />
<asp:BoundField DataField="AppointmentNotes" HeaderText="Appointment Notes" SortExpression="AppointmentNotes" />
<asp:ButtonField ButtonType="Button" CommandName="viewAppointment" Text="View" />
</Columns>
</asp:GridView>
When I click the "View" button, the gvApptList_RowCommand fires off. COde for it is:
If e.CommandName = "viewAppointment" Then
Dim tApptID As Long
gvApptList.SelectedIndex = e.CommandArgument
If IsNumeric(gvApptList.DataKeys(e.CommandArgument).Value) Then
tApptID = gvApptList.SelectedDataKey.Value
Else
Exit Sub
End If
tbAppointmentID.Text = tApptID
DisplayInfo()
End If
The gvApptList.DataKeys(e.CommandArgument).Value always comes back as nothing. What am I missing here? I have this exact sale code working on other pages.
Pertinent to your task, the correct syntax using DataKeys in ASP.NET GridView control is shown below (re: http://www.codeproject.com/Tips/225352/Nesting-GridView-control-in-ASP-NET, written in C#):
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get data key from selected row
s.SelectParameters[0].DefaultValue =Convert.ToString(((GridView)sender).DataKeys[e.Row.RowIndex].Values["AppointmentID "]);
}
}
You should obtain the reference to the Row corresponding to the command Button clicked, then extract the DataKeys value from that Row. Also, make sure that underlying DataSource contains AppointmentID field in its SELECT query.
Pertinent to your case it may look like the following (see Listing 2)
Listing 2.
protected void ViewButton_OnClick(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow row = btn.NamingContainer as GridViewRow;
string strID = gvApptList.DataKeys[row.RowIndex].Values["AppointmentID"].ToString();
int intID;
if (String.IsNotNullOrEmpty(strID)
{
intID = int.Parse(strID);
}
}
or you may use TryParse(), Convert(), etc.
Hope this may help.

Extract a BoundField to a Label

I have a DetailsView which works fine using a data access layer and a query string. However, I'd like to extract one of the fields and use it as the text in a label to go above the DetailsView as a title to that page.
Is this possible? And if so, how?
This is an abstract of the DetailsView:
<Fields>
<asp:BoundField DataField="bandname" HeaderText="Band" />
<asp:BoundField DataField="contactname" HeaderText="Contact" />
<asp:BoundField DataField="county" HeaderText="County" />
</Fields>
and the code behind:
if (Request.QueryString.Count != 0)
{
int id = int.Parse(Request.QueryString["bandid"]);
dtvBand.Visible = true;
List<Band> bandDetails = new List<Band> { BandDAL.AnonGetAllBandDetails(id) };
dtvBand.DataSource = bandDetails;
dtvBand.DataBind();
}
What I'd like to do is take the data in the first BoundField row and make it the text of a label. Pseudocode:
Label1.Text = (<asp:BoundField DataField="band")
I would not try to find the text on the DetailsView but in it's DataSource. You could use the DataBound event which is triggered after the DetailsView was databound, so it's ensured that the DataItem exists.
It depends on the Datasource of your DetailsView. Often it is a DataRowView. You have to cast it, then you can access it's column:
protected void DetailsView1_DataBound(Object sender, EventArgs e)
{
DetailsView dv = (DetailsView)sender;
string yourText = (string)((DataRowView)dv.DataItem)["ColumnName"];
Label1.Text = yourText;
}
If it's not a DataRowView use the debugger to see what dv.DataItem actually is.
I managed to achieve what I wanted using:
string titletext = dtvBand.Rows[0].Cells[1].Text.ToString();
dtvBand.Rows[0].Visible = false;
lblBand.Text = titletext;
It takes the first row of the DetailsView, puts it above the rest in a Label so it can be formatted as a header, then hides the first row of the DetailsView.
How about using a TemplateField as what Tim mentioned:
<Fields>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Band") %>' />
</ItemTemplate>
</asp:TemplateField>
</Fields>

Checkbox on GridView always returning False

I have a GridView with a Checkbox on the first column:
<asp:GridView ID="dgNumeradores" runat="server" AutoGenerateColumns="False" CellPadding="4" DataKeyNames="ItemID">
<Columns>
<asp:TemplateField HeaderText="Seleccionar">
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkChecked" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Item" DataField="Description">
</asp:BoundField>
<asp:BoundField HeaderText="Plantilla" DataField="Template">
</asp:BoundField>
</Columns>
</asp:GridView>
Now in the code behind I try to update the Checked column on the DataTable acting as datasource for the GridView (since, as you can see above, the Checkbox column is not bound to the datasource for reasons you probably know.):
Protected Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Try
For Each dr As GridViewRow In Me.dgNumeradores.Rows
Me.itemsNumTable.Select("ItemID = '" & dgNumeradores.DataKeys(dr.RowIndex).Value & "'")(0)("Checked") = DirectCast(dr.Cells(0).FindControl("chkChecked"), CheckBox).Checked
Next
'Some more unimportant-for-this-question code
Catch ex As Exception
tableInfo.ShowError(ex.Message)
End Try
End Sub
The thing is that the Checkbox.Checked always returns False.
How can I get the checked state of the Checkboxes in this scenario? Or what would be the best approach into updating the aforementioned column?
P.S. Note that click on the checkboxes doesn't post back. Nothing happens on the page until the user clicks Save (and that is the intended behavior).
Are you binding the GridView in Page Load? If that is the case use IsPostBack
IF Not IsPostBack Then
DataBind()
End IF
Should you not have the AutoPostback property set to true?
<asp:CheckBox runat="server" ID="chkChecked" AutoPostback="true" />
I have two columns in my GridView. The first column contains filenames,
the second column contains Checkboxes. Once the user has selected an arbitrary
number of Checkboxes then by clicking a button the selected files can be
downloaded.
My markup is as follows
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField HeaderText="Available Schemas"
DataField="SchemaFileName"
SortExpression="UserId">
</asp:BoundField>
<asp:TemplateField HeaderText="Select Schema">
<ItemTemplate>
<asp:CheckBox runat="server" ID="SelectedFiles" checked= '<%# Eval("checkValue") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
My CodeBehind part is as follows
protected void Page_Load(object sender, EventArgs e)
{
GenerateDownloadLinks();
if (!IsPostBack)
{
GridView1.DataSource = listOfData;
GridView1.DataBind();
}
}
listOfData is populated in GenerateDownloadLinks() and then it is bind to GridView1.
Once the user selected files and clicks download then my code loops through
the rows of the GridView and when the CheckBox is checked it updates the initially
false value of the data entry to make sure which files should be made available for
download.
protected void GetFiles_Click(object sender, EventArgs e)
{
int i = 0;
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox chkRow = (row.Cells[1].FindControl("SelectedFiles") as CheckBox);
if (chkRow.Checked)
{
listOfData[i].CheckValue = true;
}
i++;
}
}
Gridview fills perfectly even when it is not binded in Page.IsPostBack block, but here checkbox will always return false.
Bind gridview in Page.IsPostBack, and it would run perfectly fine.
Use below code
IF Not IsPostBack Then
DataBind()
End IF
And then Checkbox.Checked will return true.

ASP.NET GridView Data which i set on RowDatabound event loses after post back

I have an asp.net page where i have a gridview control which bind data from a DataTable.
In my 5 th column of the grid i am showing a Radio button list which has 2 Radio button items (Yes or No). For Some rows i will not show the RadioButton control, if the 4 th column cell value is empty. It works fine.But in my button click event (postback), the Grid is showing the Radio button list for those cells which was not shown initially. I have enabled ViewState for page and Control
This is my code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns=false
DataKeyNames="RequestDetailId" ondatabound="GridView1_DataBound" EnableViewState ="true" AllowPaging=false
onrowdatabound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="RequestDetailId" HeaderText="Request Detail Id" />
<asp:BoundField DataField="Item" HeaderText="Item" />
<asp:BoundField DataField="Status" HeaderText="Status" />
<asp:BoundField DataField="NewOffer" HeaderText="New Offer" />
<asp:TemplateField HeaderText="Your Response" ItemStyle-CssClass="radioTD">
<ItemTemplate>
<asp:RadioButtonList ID="radioList" runat="server">
<asp:ListItem Text="Yes" Value="Accept"></asp:ListItem>
<asp:ListItem Text="No" Value="Reject"></asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
in code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadItemDetails();
}
}
private void LoadItemDetails()
{
DataTable objDt= GetGridDataSource();
if (objDt.Rows.Count > 0)
{
GridView1.DataSource = objDt;
GridView1.DataBind();
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(String.IsNullOrEmpty (e.Row.Cells[3].Text.Trim())||(e.Row.Cells [3].Text ==" "))
{
e.Row.Cells[4].Text = "";
}
}
My results are
Before Postback
After Postback
How do i maintain the content after postback ? Thanks
The problem is that you are setting the Text of the GridView table cell to an empty string rather than setting the visibility of the RadioButtonList control to false.
Clearing the Text property is removing the markup for the RadioButtonList on the first load, but on postback the RowDataBound event is not fired and the RadioButtonList control is recreated and displayed again.
To avoid this you could find the control and set its visibility to false, this will then be remembered across postbacks.
Try the following:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (String.IsNullOrEmpty(e.Row.Cells[3].Text.Trim()) || (e.Row.Cells[3].Text == " "))
{
RadioButtonList radioList = (RadioButtonList)e.Row.FindControl("radioList");
radioList.Visible = false;
}
}
Hope this helps.
you can do something like this ..
from the description of the problem. it sounds as if you are doing the databinding in the code behind. in such case asp.net does not preserve the datasource in the viewstate for you. try retrieving the data and storing it in the ViewState hashtable object with something like
ViewState["GridviewData"] = GridviewData
and retreiving it from there between postbacks

Resources