GridView Page in UpdatePanel dropping 1 row - c#

I have a basic gridview with paging enabled. I have 11 rows in my database and the gridview's page size is 10. When I come to the page, it shows 10 rows, and in my pager, it shows me on page one with a link to a second page. When I click on the second page, it refreshes the page and goes to page 2 and displays the 11th, lonely row.
When I put an update panel around it, however, it drops the last row. When I come to the page, it shows the same as without the update panel. It shows 10 rows with page 1 and 2 on the pager. When I click on page 2, however, it does it's ajax thing, but doesn't display the last record on the 2nd page. Then, if I go from page 2 back to page 1, it only displays 9 rows instead of the 10 it used to display.
For some reason, when I have an update panel around my gridview, after you page once, it never displays the last row. I have tried all the different combinations of RenderMode, ChildrenAsTriggers and UpdateMode to no avail. I also have a form on the page that allows you to add new rows to the database, and consequently the gridview as well as an edit and delete link inside the gridview, all within the update panel. When I add a new row via the form or edit/delete, this doesn't happen...it only happens when I page.
Any ideas why the gridview won't display the last record/row after I page only when it's inside an update panel?
Here is the code...
ASPX
<asp:UpdatePanel runat="server" ID="uPnl" ChildrenAsTriggers="true" RenderMode="Block" UpdateMode="Always">
<ContentTemplate>
<asp:Panel runat="server" ID="pnlAddComment" CssClass="addComment" DefaultButton="btnSubmitComment">
<h1 class="postComment">Post Comment</h1>
<asp:TextBox runat="server" ID="txtName" CssClass="txtName"></asp:TextBox>
<ajaxToolkit:TextBoxWatermarkExtender ID="txtNameW" runat="server"
TargetControlID="txtName"
WatermarkText="- Type your name here -"
WatermarkCssClass="txtNameWatermark" />
<asp:RequiredFieldValidator runat="server" ID="reqName" ControlToValidate="txtName" Display="Dynamic" ErrorMessage="Please enter your name" ValidationGroup="comment"></asp:RequiredFieldValidator>
<asp:TextBox runat="server" ID="txtComment" TextMode="MultiLine" CssClass="txtComment"></asp:TextBox>
<ajaxToolkit:TextBoxWatermarkExtender ID="TBWE2" runat="server"
TargetControlID="txtComment"
WatermarkText="- Write anything you'd like about this event -"
WatermarkCssClass="txtCommentWatermark" />
<asp:RequiredFieldValidator runat="server" ID="reqComment" ControlToValidate="txtComment" Display="Dynamic" ErrorMessage="Please enter your comment" ValidationGroup="comment"></asp:RequiredFieldValidator>
<div class="buttons">
<asp:Button runat="server" ID="btnSubmitComment" ValidationGroup="comment" Text="Submit Comment" />
<span class="loader">Saving</span>
</asp:Panel>
<h1>Recent Comments</h1>
<a name="comments"> </a>
<asp:GridView runat="server" ID="gvComments" DataKeyNames="CommentID" PagerSettings-Position="TopAndBottom" AllowPaging="true" PageSize="10" AutoGenerateColumns="false" GridLines="None" CssClass="comments">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div class="comment user">
<p>
<img src="images/icon.gif" width="46" height="55" />
<%#Eval("UserComment")%>
<span>
Posted by <%#Eval("UserName")%> <br/>
on <%#Format(Eval("DateCreated"), "MM/dd/yyyy")%> at <%#Format(Eval("DateCreated"), "h:mm tt")%>
</span>
<asp:LinkButton runat="server" CausesValidation="false" ID="lnkEdit" CssClass="edit" CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkDelete" CommandArgument='<%#Eval("CommentID")%>' CssClass="delete" OnClientClick="return confirm('Are you sure you want to delete this comment?');" CausesValidation="false" OnClick="DeleteComment" Text="Delete"></asp:LinkButton>
</p>
</div>
</ItemTemplate>
<EditItemTemplate>
<div class="comment user">
<p>
<img src="images/icon.gif" width="46" height="55" />
<label>Name:</label>
<asp:TextBox runat="server" ID="txtNameEdit" Width="240" Text='<%#Eval("UserName")%>'></asp:TextBox><br />
<label>Comment:</label>
<asp:TextBox runat="server" TextMode="MultiLine" ID="txtCommentEdit" Width="240" Height="100" Text='<%#Eval("UserComment") %>'></asp:TextBox>
<asp:LinkButton runat="server" ID="lnkCancel" CommandName="Cancel" CssClass="cancel" CausesValidation="false" Text="Cancel"></asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkUpdate" CommandName="Update" CssClass="update" CausesValidation="false" Text="Update"></asp:LinkButton>
</p>
</div>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="grdFooter" HorizontalAlign="right" />
<PagerSettings PageButtonCount="7" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
VB Code Behind
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
bindComments()
End If
End Sub
Private Sub bindComments()
gvComments.DataSource = dataaccess.getdataset("SELECT * FROM Comments ORDER BY DateCreated DESC", Data.CommandType.Text)
gvComments.DataBind()
End Sub
Protected Sub gvComments_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles gvComments.RowEditing
gvComments.EditIndex = e.NewEditIndex
bindComments()
End Sub
Protected Sub gvComments_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles gvComments.RowCancelingEdit
gvComments.EditIndex = -1
bindComments()
End Sub
Protected Sub gvComments_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles gvComments.PageIndexChanging
gvComments.PageIndex = e.NewPageIndex
bindComments()
End Sub
Protected Sub btnSubmitComment_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSubmitComment.Click
Dim userType As String = "attendee"
If Not IsNothing(Request.QueryString("user")) AndAlso Request.QueryString("user").Length > 0 Then
userType = Request.QueryString("user")
End If
dataaccess.NoReturnQuery("INSERT INTO Comments (UserName, UserComment, UserType) VALUES ('" & txtName.Text.Replace("'", "''") & "','" & txtComment.Text.Replace("'", "''").Replace(vbCrLf, "<br />") & "','" & userType & "')", Data.CommandType.Text)
txtComment.Text = ""
txtName.Text = ""
gvComments.PageIndex = 0
bindComments()
End Sub
Sub DeleteComment(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lnk As LinkButton = TryCast(sender, LinkButton)
If Not IsNothing(lnk) AndAlso IsNumeric(lnk.CommandArgument) Then
dataaccess.NoReturnQuery("DELETE FROM Comments WHERE CommentID = " & lnk.CommandArgument, Data.CommandType.Text)
bindComments()
End If
End Sub
Protected Sub gvComments_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvComments.RowUpdating
Dim row As GridViewRow = gvComments.Rows(e.RowIndex)
Dim txtCommentEdit As TextBox = CType(row.FindControl("txtCommentEdit"), TextBox)
Dim txtNameEdit As TextBox = CType(row.FindControl("txtNameEdit"), TextBox)
dataaccess.NoReturnQuery("UPDATE Comments SET UserComment = '" & txtCommentEdit.Text.Replace("'", "''").Replace(vbCrLf, "<br />") & "', UserName = '" & txtNameEdit.Text.Replace("'", "''") & "' WHERE CommentID = " & gvComments.DataKeys(e.RowIndex).Value, Data.CommandType.Text)
gvComments.EditIndex = -1
bindComments()
End Sub
Protected Sub gvComments_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvComments.RowDataBound
Dim lnkDelete As LinkButton = CType(e.Row.FindControl("lnkDelete"), LinkButton)
If Not IsNothing(lnkDelete) Then
If Request.QueryString("user") = "admin" Then
lnkDelete.Visible = True
Else
lnkDelete.Visible = False
End If
End If
Dim lnkEdit As LinkButton = CType(e.Row.FindControl("lnkEdit"), LinkButton)
If Not IsNothing(lnkEdit) Then
If Request.QueryString("user") = "admin" Then
lnkEdit.Visible = True
Else
lnkEdit.Visible = False
End If
End If
End Sub

Try this from the code-behind on Page_Load:
ScriptManager.RegisterAsyncPostBackControl(gvComments);

Related

Parser Error When Referring Control Value as ASPX Expression

ASPX Code
<asp:RadioButtonList ID="rblApprovalSelection" runat="server"
<asp:ListItem Value="1">Item1</asp:ListItem>
<asp:ListItem Value="2">Item2</asp:ListItem>
<asp:ListItem Value="3" Selected="True">Item3</asp:ListItem>
<asp:ListItem Value="4">Item4</asp:ListItem>
<asp:ListItem Value="5">Item5</asp:ListItem>
</asp:RadioButtonList>
<asp:BoundField DataField="MyData"
Visible='<%#IIf(rblApprovalSelection.SelectedItem.Value=3, False, True) %>'
HeaderText="DataHeader" />
In my above code the below mentioned part is failed and throws error.
Visible='<%#IIf(rblApprovalSelection.SelectedItem.Value=3, False, True) %>'
As suggested by VDWWD the above code should be read as IF instead of IIF().
Error Message
Ok, you don't note/mention how you setting the value of the radio button list.
And since you want to hide/show the value, then I suggest better not to hide the cell, but hide a control in the cell (so it will not mess up grid formatting).
So, say this markup:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover"
Width="50%" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="Firstname" HeaderText="Firstname" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="From City" />
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<asp:RadioButtonList ID="rblApprovalSelection" runat="server"
AutoPostBack="true"
OnSelectedIndexChanged="rblApprovalSelection_SelectedIndexChanged" >
<asp:ListItem Value="1">Item1</asp:ListItem>
<asp:ListItem Value="2">Item2</asp:ListItem>
<asp:ListItem Value="3" Selected="True">Item3</asp:ListItem>
<asp:ListItem Value="4">Item4</asp:ListItem>
<asp:ListItem Value="5">Item5</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText ="Description">
<ItemTemplate>
<asp:Label ID="lblDesc" runat="server"
Text='<%# Eval("Description") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
So, note how I added a autopost-back for the RB list.
And our code to fill the gv is thus this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String =
"SELECT * FROM tblhotelsA ORDER BY HotelName"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
Dim rstData As New DataTable
rstData.Load(cmdSQL.ExecuteReader)
GridView1.DataSource = rstData
GridView1.DataBind()
End Using
End Using
End Sub
But, we need a row data bound event to hide/show that column based on RB seleting.
so, this:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim RB As RadioButtonList = e.Row.FindControl("rblApprovalSelection")
Dim lblDesc As Label = e.Row.FindControl("lblDesc")
lblDesc.Visible = RB.SelectedItem.Value <> 3
End If
End Sub
And the code for the RB change is much the same as the row data binding.
So, this code:
Protected Sub rblApprovalSelection_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim RB As RadioButtonList = sender
Dim gRow As GridViewRow = RB.NamingContainer
Dim lblDesc As Label = gRow.FindControl("lblDesc")
lblDesc.Visible = RB.SelectedItem.Value <> 3
End Sub
And thus we get this result:
So, for a standard GV, I suggest both the RB, and a label templated column, and not use cells (which are for defaulted databound columns). For any non "data bound" column, then you don't use cells, but can/should/will use findcontrol as per above.

how to add different control in gridview row

I have a gridview which I populate from the list data. every row in the gridview has a text box. there is one row within the gridview which I want a dropdown control rather then the textbox. I can't figure out how to change the textbox to dropdown control from a row in the grid.
My gridview below:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" style="width:100%;" ShowHeader="false"
CellPadding="3" BackColor="White" ForeColor="Black" Font-Bold="false" GridLines="None"
RowStyle-CssClass="GridRow">
<Columns>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lbl_ItemID" runat="server" Text='<%# Eval("GroupItemTypeID") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="false">
<ItemTemplate>
<asp:Label ID="lbl_ItemCode" runat="server" Text='<%# Eval("GroupItemTypeCode") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-Width="310px" >
<ItemTemplate>
<asp:Label ID="lbl_ItemValuesName" runat="server" Text='<%# Eval("ControlName") %>' ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-Width="245px">
<ItemTemplate>
<asp:TextBox ID="txtPrice" runat="server" CssClass="form-control"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-CssClass="RowWid">
<ItemTemplate>
<asp:Label ID="lbl_IsPercentbased" runat="server" Text='<%# Eval("PercentBasedText") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-Width="70px">
<ItemTemplate>
<asp:CheckBox ID="ChkIsPercent" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind
private void GetItemValues()
{
List<Entities.ItemValues> IValues = new List<Entities.ItemValues>();
IValues = BLL.PriceGroupItemValues.GetAllPriceGroupItemValues();
GridView1.DataSource = IValues;
GridView1.DataBind();
}
You can go for this approach in your case :
Put a TextBox and DropDown both in that TemplateField where your TextBox is currently, and set Visible=false in your Dropdown.
Now in your code-behind, you can use the GridView.RowDataBound event to alternatively display the TextBox or the Dropdown whenever and wherever you require. Something like this :
public void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// set Dropdown visible = true/false as per your requirement.
}
else
{
// set Textboxvisible = true/false as per your requirement.
}
}
This event will fire up for ear row in your GridView and based on the condition that is specified, you can manipulate which control you want to show in that particular row. You can find the dropdown control like this :
foreach (GridViewRow row in GridView1.Rows)
{
categoryName = ((DropDownList)row.FindControl("ddlCategoryName"));
}
Hope this helps.
Use a placeholder control instead of a textbox and programmatically add either a textbox or DDL to the Placeholder control in the rowdatabound event based on your criteria
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1"
DataKeyNames="user_id">
<Columns>
<asp:BoundField DataField="user_id" HeaderText="user_id" ReadOnly="True" InsertVisible="False"
SortExpression="user_id"></asp:BoundField>
<asp:BoundField DataField="user_logon" HeaderText="user_logon" SortExpression="user_logon">
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Sample DataSources
'Primary Datasource to bind to the gridview
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString='<%$ ConnectionStrings:SomeConnectionString %>'
SelectCommand="select top 10 user_id, user_logon from your_user_table"></asp:SqlDataSource>
'Secondary datasource to bind to the ddl
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString='<%$ ConnectionStrings:SomeConnectionString %>'
SelectCommand="select top 5 user_id, user_logon from your_user_table"></asp:SqlDataSource>
Code behind, based on the whether the user_id is odd or even I place one or the other control:
Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ph As PlaceHolder = e.Row.FindControl("PlaceHolder1")
If GridView1.DataKeys(e.Row.RowIndex).Value Mod 2 = 0 Then
Dim tb As New TextBox()
tb.Enabled = False
tb.Text = CType(e.Row.DataItem, DataRowView)("user_logon")
ph.Controls.Add(tb)
Else
Dim ddl As New DropDownList()
ddl.DataSourceID = SqlDataSource2.ID
ddl.DataTextField = "user_logon"
ddl.DataValueField = "user_id"
ph.Controls.Add(ddl)
ddl.DataBind()
End If
End If
End Sub
EDIT based on your Comments:
Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ph As PlaceHolder = e.Row.FindControl("PlaceHolder1")
If CType(e.Row.DataItem, DataRowView)("GroupItemTypeID") ="SUBFREQ" Then
Dim ddl As New DropDownList()
ddl.DataSourceID = <substitute your requirements>
ddl.DataTextField = ...
ddl.DataValueField = ...
ph.Controls.Add(ddl)
ddl.DataBind()
Else
Dim tb As New TextBox()
tb.Enabled = ...whatever...
tb.Text = CType(e.Row.DataItem, DataRowView)("GroupItemTypeID")
ph.Controls.Add(tb)
End If
End If
End Sub
Did some work around with the solution Harvey provided and my existing code. Posting my answer here.
In the gridview, created 2 control and visibility of one control(dropdown) to false
<asp:TemplateField ItemStyle-Width="245px">
<ItemTemplate>
<asp:TextBox ID="txtPrice" runat="server" CssClass="form-control"></asp:TextBox>
<asp:DropDownList ID="ddFrequencyBilling" runat="server" CssClass="form-control" Visible="false"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
In the RowDataBound event of the gridview
if (e.Row.RowType == DataControlRowType.DataRow)
{
//foreach( GridViewRow row in GridView1.Rows)
//{
String ItemCode = (e.Row.FindControl("lbl_ItemCode") as Label).Text;
if ( ItemCode == "SUBFREQ")
{
List<Entities.ItemValues> PGItemValues = new List<Entities.ItemValues>();
TextBox TextBoxtemp = ((TextBox)e.Row.FindControl("txtPrice"));
TextBoxtemp.Visible = false;
Label lbel = ((Label)e.Row.FindControl("lbl_IsPercentbased"));
lbel.Visible = false;
CheckBox chk = ((CheckBox)e.Row.FindControl("ChkIsPercent"));
chk.Visible = false;
DropDownList dd1 = ((DropDownList)e.Row.FindControl("ddFrequencyBilling"));
dd1.Visible = true;
PGItemValues = BLL.PriceGroupItemValues.GetItemValueOnCode(ItemCode, 1);
dd1.DataSource = PGItemValues;
dd1.DataTextField = "IValue";
dd1.DataValueField = "ItemCode";
dd1.DataBind();
}
//}
}
and yes it worked. Thanks alot guys.

Dynamically generate page linkbuttons for the PagerTemplate of a GridView

From the MSDN page for the PagerTemplate of the GridView control (emphasis mine):
Typically, button controls are added to the pager template to perform the paging operations. The GridView control performs a paging operation when a button control with its CommandName property set to "Page" is clicked. The button's CommandArgument property determines the type of paging operation to perform.
"Next": Navigates to the next page.
"Prev": Navigates to the previous page.
"First": Navigates to the first page.
"Last": Navigates to the last page.
Integer value: Navigates to the specified page number.
Source: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.pagertemplate(v=vs.110).aspx
This stuff is pretty straightforward for the next/prev/first/last buttons because of their static nature.
<PagerTemplate>
<table>
<tr>
<td>
<asp:Button CommandName="Page" CommandArgument="First" Enabled="<%# Model.PageContext.HasPrevious %>" Text="First" runat="server" />
</td>
<td>
<asp:Button CommandName="Page" CommandArgument="Prev" Enabled="<%# Model.PageContext.HasPrevious %>" Text="Previous" runat="server" />
</td>
<td>
<asp:Button CommandName="Page" CommandArgument="Next" Enabled="<%# Model.PageContext.HasNext %>" Text="Next" runat="server" />
</td>
<td>
<asp:Button CommandName="Page" CommandArgument="Last" Enabled="<%# Model.PageContext.HasNext %>" Text="Last" runat="server" />
</td>
</tr>
</table>
</PagerTemplate>
On the other hand, the CommandArgument for numeric buttons has to be dynamic and unique for each page that can be navigated to. I'm guessing I will need a for-loop or a repeater control to get the right number of page links on the user's display.
Nothing I've tried seems to just work. My for-loop code doesn't even compile.
<% for (int pageIndex = 0; pageIndex < Model.PageContext.PageCount; pageIndex++) { %>
<asp:LinkButton CommandName="Page" CommandArgument="<%= pageIndex %>" Text="<%= pageIndex + 1 %>" runat="server"/>
<% } %>
My alternative approach uses a Repeatercontrol and does compile, but the Repeatercontrol itself handles the ItemCommand for each button, preventing the "Page" ItemCommand events from bubbling up to the GridView.
<asp:Repeater ItemType="System.Int32" SelectMethod="GetPages" runat="server">
<ItemTemplate>
<asp:LinkButton CommandName="Page" CommandArgument="<%# Item %>" Text="<%# Item + 1 %>" runat="server" />
</ItemTemplate>
</asp:Repeater>
Each button raises the correct event, but the events never reach the GridView because they are handled at a lower level by the Repeater control. I have to attach an event handler that listens for RepeaterCommandEventArgs and then set the new page index on the GridView myself.
*Takes deep breath*
Can I add numeric page buttons without having to wire up events myself?
The result that I'm trying to achieve, based on the code above:
I found an even simpler way, one that is framework 4.0 compatible
<asp:GridView ID="GridView_History" runat="server">
<PagerTemplate>
<asp:LinkButton ID="lnkPrev" runat="server" CommandName="Page" CommandArgument="Prev">Prev</asp:LinkButton>
<asp:Repeater ID="rptPagesHistory" OnItemDataBound="rptPagesHistory_ItemDataBound" runat="server" OnLoad="rptPagesHistory_Load">
<ItemTemplate>
<asp:LinkButton ID="lnkPageNumber" CommandName="Page" runat="server" OnClick="lnkPageNumberHistory_Click" />
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton ID="lnkNext" runat="server" CommandName="Page" CommandArgument="Next">Next</asp:LinkButton>
</PagerTemplate>
</asp:GridView>
protected void rptPagesHistory_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
LinkButton lnkPageNumber = new LinkButton();
System.Int32 pageNumber = (System.Int32)e.Item.DataItem;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
lnkPageNumber = (LinkButton)e.Item.FindControl("lnkPageNumber");
lnkPageNumber.Text = pageNumber;
lnkPageNumber.CommandArgument = pageNumber - 1;
}
}
protected void rptPagesHistory_Load(object sender, EventArgs e)
{
Repeater rpt = (Repeater)sender;
rpt.DataSource = Enumerable.Range(1, GridView_History.PageCount);
rpt.DataBind();
}
protected void lnkPageNumberHistory_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)sender;
GridView_History.PageIndex = btn.CommandArgument;
GridView_History.DataBind();
}
I figured out a way to get it done using the Repeater control.
First, populate the repeater with link buttons for each page index (1-based) and attach an event handler for the OnItemCommand event.
<asp:Repeater runat="server" ItemType="System.Int32" SelectMethod="GetPages" OnItemCommand="OnRepeaterCommand">
<ItemTemplate>
<asp:LinkButton CommandName="Page" CommandArgument="<%# Item %>" Text="<%# Item %>" runat="server" />
</ItemTemplate>
</asp:Repeater>
Pay special attention to how I'm binding my repeater to the collection of int that is returned by GetPages.
public IEnumerable<int> GetPages()
{
return Enumerable.Range(1, this.PageCount);
}
Finally, in the event handler, re-insert the CommandEventArgs into the event pipeline using some reflection-fu.
protected void OnRepeaterCommand(object source, RepeaterCommandEventArgs e)
{
source.GetType()
.GetMethod("RaiseBubbleEvent", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(source, new[]
{
e.CommandSource,
new CommandEventArgs(e.CommandName, e.CommandArgument)
});
}
That's it. You don't have to do anything else. The GridView will handle the ItemCommand and set the page index to the new value.
Here is the code, lifted right from the page(s).
<asp:GridView ID="grdUsage" PageSize="20" Width="100%" runat="server" AllowPaging="True" AllowSorting="False" CellPadding="4" ForeColor="#333333" GridLines="None" Font-Size="14px" Font-Bold="false" OnPageIndexChanging="grdUsage_PageIndexChanging" OnRowDataBound="grdUsage_RowDataBound" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="ID" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="100px" ItemStyle-Font-Size="12px">
<ItemTemplate>
<asp:Literal ID="lCampaignID" runat="server"></asp:Literal>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:HyperLink ID="lnkCampaign" runat="server" Target="_blank" Font-Size="12px"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EditRowStyle BackColor="#2461BF" />
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#EFF3FB" />
<SelectedRowStyle BackColor="#D1DDF1" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#F5F7FB" />
<SortedAscendingHeaderStyle BackColor="#6D95E1" />
<SortedDescendingCellStyle BackColor="#E9EBEF" />
<SortedDescendingHeaderStyle BackColor="#4870BE" />
<AlternatingRowStyle BackColor="White" />
<PagerStyle HorizontalAlign="Center" BackColor="white" />
<PagerTemplate>
<ul class="pagination">
<li>
<asp:LinkButton ID="lnkPrev" runat="server" CommandName="Page" CommandArgument="Prev"><span>«</span></asp:LinkButton></li>
<asp:Repeater ID="rptPagesUsage" OnItemDataBound="rptPagesUsage_ItemDataBound" runat="server" OnLoad="rptPagesUsage_Load">
<ItemTemplate>
<asp:Literal ID="lListItem" runat="server"><li></asp:Literal><asp:LinkButton ID="lnkPageNumber" CommandName="Page" runat="server" OnClick="lnkPageNumberUsage_Click" /></li>
</ItemTemplate>
</asp:Repeater>
<li>
<asp:LinkButton ID="lnkNext" runat="server" CommandName="Page" CommandArgument="Next"> <span>»</span></asp:LinkButton></li>
</ul>
</PagerTemplate>
</asp:GridView>
Sub pGrid(sql as string) '
grdUsage.DataSource = G_GetDataTable(sql)
grdUsage.DataBind()
If grdUsage.Rows.Count > 0 Then
grdUsage.HeaderRow.Cells(1).Text = String.Format("Associated Campaigns for: <i>{0}</i>", txtEMailTitle.Text)
End If
End Sub
Protected Sub rptPagesUsage_Load(sender As Object, e As EventArgs)
Dim rpt As Repeater = DirectCast(sender, Repeater)
rpt.DataSource = Enumerable.Range(1, grdUsage.PageCount)
rpt.DataBind()
End Sub
Protected Sub rptPagesUsage_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
Dim lListItem As New Literal()
Dim lnkPageNumber As New LinkButton()
Dim pageNumber As System.Int32 = DirectCast(e.Item.DataItem, System.Int32)
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
lListItem = DirectCast(e.Item.FindControl("lListItem"), Literal)
lnkPageNumber = DirectCast(e.Item.FindControl("lnkPageNumber"), LinkButton)
lnkPageNumber.Text = pageNumber
lnkPageNumber.CommandArgument = pageNumber - 1
If e.Item.ItemIndex = grdUsage.PageIndex Then
lListItem.Text = "<li class=""active"">"
End If
End If
End Sub
Protected Sub grdUsage_PageIndexChanging(sender As Object, e As GridViewPageEventArgs)
hSelectedTab.Value = 5
If e.NewPageIndex >= 0 Then
grdUsage.PageIndex = e.NewPageIndex
pGrid(sql)
End If
End Sub
Protected Sub grdUsage_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Dim drview As DataRowView = DirectCast(e.Row.DataItem, DataRowView)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim lnkCampaign As HyperLink = DirectCast(e.Row.FindControl("lnkCampaign"), HyperLink)
Dim lCampaignID As Literal = DirectCast(e.Row.FindControl("lCampaignID"), Literal)
lnkCampaign.Text = drview("CampaignTitle").ToString()
lCampaignID.Text = drview("EmailCampaignID").ToString()
lnkCampaign.NavigateUrl = String.Format("/Admin/WF_Admin_Campaign_Email_Detail.aspx?ID={0}", drview("EmailCampaignID").ToString())
End If
End Sub
Protected Sub lnkPageNumberUsage_Click(sender As Object, e As EventArgs)
Dim btn As LinkButton = DirectCast(sender, LinkButton)
grdUsage.PageIndex = btn.CommandArgument
pGrid(sql)
End Sub
I also created an extension for the grid that is also in use.
Public Module ControlUtilities
<Extension()>
Public Sub CustomPager(ByRef grd As GridView)
Dim cp As New clsCustomPager(grd)
End Sub
Public Class clsCustomPager
Public _grd As GridView
Public Property rpt() As GridView
Get
Return _grd
End Get
Set(value As GridView)
_grd = value
End Set
End Property
Public Sub New(ActiveGridView As GridView)
_grd = ActiveGridView
Me.CustomPages()
End Sub
''' <summary>
''' create the objects needed for a bootstrap driven navigation for a gridview
''' </summary>
Sub CustomPages()
If Not _grd Is Nothing And Not _grd.BottomPagerRow Is Nothing Then
'hook event handler to grid
AddHandler _grd.PageIndexChanging, AddressOf Me.Grid_PageIndexChanging
'declare variables
Dim pagerRow As GridViewRow = _grd.BottomPagerRow
Dim lnkPrev As LinkButton = New LinkButton()
Dim lnkNext As LinkButton = New LinkButton()
'set up previous link
lnkPrev.CommandArgument = "Prev"
lnkPrev.CommandName = "Page"
lnkPrev.Text = "<span>«</span>"
'set up next link
lnkNext.CommandArgument = "Next"
lnkNext.CommandName = "Page"
lnkNext.Text = "<span>»</span>"
'create html unordered list
pagerRow.Cells(0).Controls.Add(New LiteralControl("<ul class=""pagination"">"))
'add previous link
pagerRow.Cells(0).Controls.Add(New LiteralControl("<li>"))
pagerRow.Cells(0).Controls.Add(lnkPrev)
pagerRow.Cells(0).Controls.Add(New LiteralControl("</li>"))
Dim pageNumber As Integer
For Each pageNumber In Enumerable.Range(1, _grd.PageCount)
'create page link object
Dim lnkPage As LinkButton = New LinkButton()
lnkPage.CommandName = "Page"
lnkPage.Text = pageNumber
lnkPage.CommandArgument = (pageNumber - 1)
AddHandler lnkPage.Click, AddressOf Me.lnkPageNumber_Click 'event handler
'set css class if selected or not
If (pageNumber - 1) = _grd.PageIndex Then
pagerRow.Cells(0).Controls.Add(New LiteralControl("<li class=""active"">"))
Else
pagerRow.Cells(0).Controls.Add(New LiteralControl("<li>"))
End If
'add lnk and close html listitem
pagerRow.Cells(0).Controls.Add(lnkPage)
pagerRow.Cells(0).Controls.Add(New LiteralControl("</li>"))
Next
'add next link
pagerRow.Cells(0).Controls.Add(New LiteralControl("<li>"))
pagerRow.Cells(0).Controls.Add(lnkNext)
pagerRow.Cells(0).Controls.Add(New LiteralControl("</li>"))
'close up unordered list
pagerRow.Cells(0).Controls.Add(New LiteralControl("</ul>"))
End If
End Sub
''' <summary>
''' event handler for previous/next buttons
''' </summary>
Protected Sub Grid_PageIndexChanging(sender As Object, e As GridViewPageEventArgs)
If e.NewPageIndex >= 0 Then
_grd.PageIndex = e.NewPageIndex
_grd.DataBind()
Me.CustomPages()
End If
End Sub
''' <summary>
''' event handler for numeric link buttons
''' </summary>
Protected Sub lnkPageNumber_Click(sender As Object, e As EventArgs)
Dim btn As LinkButton = DirectCast(sender, LinkButton)
_grd.PageIndex = btn.CommandArgument
_grd.DataBind()
Me.CustomPages()
End Sub
End Class
End Module

Assign Gridview values to text box

I have to ask about A question in C#,Asp.net... i created 3 textbox for empid, name and Address
If i Click the "Edit Button" with manually type empid in a text box. i want to assign other two values name & Address to their textbox. then after i use update button to update
Can anyone teach me with code?
//Asp.net
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Empid" Width="50px"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:Label ID="Label2" runat="server" Text="Name" Width="50px"></asp:Label>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<br />
<asp:Label ID="Label3" runat="server" Text="Address" Width="50px"></asp:Label>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<br />
<br />
<br />
<br />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
</div>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="update " />
<asp:Button ID="Button2" runat="server" Text="Edit" Width="61px" />
</form>
//Cs for update button
SqlConnection conn = new SqlConnection("Data Source=s\\SQLEXPRESS;Initial catalog = sample;Integrated security=True");
SqlCommand cmd = new SqlCommand("UPDATE empdetails SET Name='" + TextBox2.Text + "',Address='" + TextBox3.Text + "' WHERE Empid ='" + TextBox1.Text + "'", conn);
conn.Open();
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT * FROM Empdetails";
GridView.DataSource = cmd.ExecuteReader();
GridView.DataBind();
TextBox1.Text = "";
TextBox2.Text = "";
TextBox3.Text = "";
conn.Close();
I code like this ,if i Edit Button, with entered Empid, i want other values name & Address ll assign to text box
Steps:
Get the Employee details in GridView.
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
GetEmpDetails()
End Sub
Private Sub GetEmpDetails()
SqlConnection conn = new SqlConnection("Data Source=s\\SQLEXPRESS;Initial catalog = sample;Integrated security=True");
conn.Open();
cmd.CommandText = "SELECT * FROM Empdetails";
GridView.DataSource = cmd.ExecuteReader();
GridView.DataBind();
End Sub
Add this Property AutoGenerateSelectButton="True" to the gridview in the design page.
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
AutoGenerateSelectButton="True"
CellPadding="4" >
</asp:GridView>
On the SelectedIndexChanged of the Grid get the RowIndex so that we will get the row value of the row selected.
Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles GridView1.SelectedIndexChanged
LoadValues(GridView1.SelectedRow.RowIndex)
End Sub
Then Load the grid values to the respective textbox.
And change the values you want but don't change the ID (Highly recommended)
Then Click UpdateButton. Call Update Query there.
Load grid value again and bind it. So that you can see the change instantly.
Happy Coding..!! :)

Show as many columns to fit GridView width ASP.NET

I have a GridView which is populated by images from my database. My current GridView looks like that:
But I would like to fit my grid width, like this:
And here is my code:
<asp:GridView runat="server" ID="GridView1" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" Width="100%" GridLines="None">
<Columns>
<asp:ImageField DataImageUrlFormatString="http://myurl/{0}" DataImageUrlField="url" ControlStyle-Height="200px" ControlStyle-Width="200px">
<ControlStyle Height="200px" Width="200px"></ControlStyle>
</asp:ImageField>
</Columns>
</asp:GridView>
Any help appriciated.
You can use datalist instead of gridview in this case having 3 columns
It works nearly same as gridview.
<asp:DataList ID="dlImages" runat="server" RepeatColumns="4" CellPadding="3" CellSpacing="3"
RepeatDirection="Horizontal">
<ItemTemplate>
<table class="TableBorder">
<tr>
<td class="NormalTextBig" valign="top" align="left">
<%#Container.ItemIndex + 1%>.
</td>
</tr>
<tr>
<td valign="top" align="left">
<asp:ImageButton ID="ImageButton1" runat="server" CommandName="ImageClick" CommandArgument='<%# Eval("PageName") %>' />
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
Binding:
Protected Sub dlImages_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles dlImages.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.Item Then
CType(e.Item.FindControl("ImageButton1"), ImageButton).ImageUrl = "ImageResize.aspx?ImageName=ScreenMasterImages/" & e.Item.DataItem("ImgName") & "&BoxSize=" & 300
CType(e.Item.FindControl("ImageButton1"), ImageButton).ToolTip = e.Item.DataItem("PageName")
End If
End Sub
I have used this code for same purpose like you mentioned in my project.
ItemCommand:
Protected Sub dlImages_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) Handles dlImages.ItemCommand
If e.CommandName = "ImageClick" Then
Session("ImageName") = e.CommandArgument
Response.Redirect("ScreenDetails.aspx")
End If
End Sub
This is how it will look:
I think you have similar thing to do :)

Categories

Resources