I have an asp.net gridview that is originally bound to a sqldatasource control, but when the user presses an external button, it instead gets the contents of a datatable rather than a SQLdatasource control. I therefore had to write code in the PageIndexChanging event of the gridview to allow for paging. My code is as follows:
Protected Sub gvEvents_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles gvEvents.PageIndexChanging
gvEvents.PageIndex = e.NewPageIndex
gvEvents.DataBind()
This worked beautifully until I added an AJAX update panel so the whole page wouldn't postback every time it paged, and paging stopped working. I debugged it and discovered that it is actually calling the PageIndexChanging event, but nothing is happening.
I searched the web and found a few people with the same problem, but their solutions did not work for me. There was one on this site whose problem was solved by the following:
In PageIndexchanging event, where you bind data to grid, make sure, data is again fetched from the DB
I don't know what that means; my data was being bound as demonstrated above. I have "enable paging" set to true and EnableSortingAndPagingCallbacks set to false.
I would really appreciate if someone can help me. I am including my markup for the updatepanel below. Thank you so much!
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ibtnSearch" />
</Triggers>
<ContentTemplate>
<asp:GridView ID="gvEvents" runat="server" DataKeyNames = "intID"
AutoGenerateColumns="False" AllowPaging="True" GridLines="None" CellPadding="10"
ForeColor="#333333" PageSize="6" DataSourceID="defaultDS" >
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<Columns>
<asp:TemplateField HeaderText="Date">
<ItemTemplate>
<!-- put code block inside label? To set the formatter to include year if
it's next year? -->
<asp:Label ID="Label1" runat="server"
Text = '<%# RepeatingMethods.DetermineOngoing(CType(Eval("dtmEventStartDate"), DateTime) , CType(Eval("dtmEventEndDate"), DateTime))%>'> </asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Eval("chvAgeRange") %>'> </asp:Label> <br />
<asp:Label ID="Label3" runat="server" Text= '<%# Eval("chvState") %>'> </asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:HyperLinkField DataNavigateUrlFields="intId"
DataNavigateUrlFormatString="EventDetail.aspx?intId={0}"
DataTextField="chvEventName" />
<asp:BoundField DataField="chvBriefDescription" HeaderText="Description"
SortExpression="chvBriefDescription" />
</Columns>
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White"></FooterStyle>
<PagerStyle HorizontalAlign="Center" BackColor="#FFCC66" ForeColor="#333333"></PagerStyle>
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy"></SelectedRowStyle>
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White"></HeaderStyle>
<AlternatingRowStyle BackColor="White"></AlternatingRowStyle>
</asp:GridView>
<asp:Label ID="lblError" runat="server"></asp:Label>
<br />
</ContentTemplate>
</asp:UpdatePanel>
In PageIndexchanging event, where you bind data to grid, make sure, data is again fetched from the DB
I don't know what that means; my data was being bound as demonstrated above.
It means that you need to fetch your data again in your code behind page. You are using a SQLdatasource in your design/html page, so you need to remove that and use a SQL Connection, SQL Command, etc. to fetch your data and then set that as your control's datasource.
Something like below:
http://www.aspnettutorials.com/tutorials/database/db-grid-aspnet2-vb.aspx
Your code should look something like this
Protected Sub Page_Load(...)
gvEvents.PageIndex = 0
LoadData();// loads initial data
end sub
private sub LoadData()
'' do your SQL Conn and Command here
'' set your datasource of gridview here
end sub
Protected Sub gvEvents_PageIndexChanging(...) Handles gvEvents.PageIndexChanging
gvEvents.PageIndex = e.NewPageIndex
LoadData()
gvEvents.DataBind()
end sub
For anyone who stumbles across this issue, I encountered it this AM and this post was misleading (atleast for my scenario). For me, I simply had to add a PageIndexChanging Event as a trigger for my datagrid for the updatepanel trigger's, and it resolved my issue.
Controls that Are Not Compatible with UpdatePanel Controls
The following ASP.NET controls are not compatible with partial-page updates, and are therefore not supported inside an UpdatePanel control:
GridView and DetailsView controls when their EnableSortingAndPagingCallbacks property is set to true. The default is false.
http://www.asp.net/Ajax/Documentation/Live/overview/UpdatePanelOverview.aspx
Just update the AJAX Panel after databind().
assume id of the Update Panel is AJAXPanel
Protected Sub gvEvents_PageIndexChanging(...) Handles gvEvents.PageIndexChanging
gvEvents.PageIndex = e.NewPageIndex
LoadData()
gvEvents.DataBind()
// The below line refreshes the update panel..
AJAXPanel.Update()
end sub
Related
Hi guys,
I am not a developer but I always try my best to manage my page coding by myself before bothering anyone and by checking many examples and apply them to my web application, but this time I really surrendered and had to ask.
I have a Gridview where I will be using to update one field which is CHECKBOX.
The gridview has a checkbox control where it's checked attribute need to be True or False based on the Database value.
Values are 1 and 2 only
I wrote the below code to catch the cell label and change the checkbox attribute but it didn't work
Protected Sub Refill_checkbox(ByVal sender As Object, ByVal e As System.EventArgs)
Dim i As Integer
For i = 0 To dg.Rows.Count - 1
Dim Test As String = CType(dg.Rows(i).Cells(3).FindControl("Att_Type"), Label).Text
If CType(dg.Rows(i).Cells(4).FindControl("Att_Type"), Label).Text = 1 Then
CType(dg.Rows(i).Cells(6).FindControl("CheckBox_Attendance"), CheckBox).Checked = True
Else
CType(dg.Rows(i).Cells(6).FindControl("CheckBox_Attendance"), CheckBox).Checked = False
End If
Response.Write(Test)
Next
End Sub
Unfortunately it even did not write the Test Variable to find if it catches the label from the gridview or not.
My Gridview is as following:
<asp:GridView ID="dg" runat="server" BorderColor="#CCCCCC" BorderStyle="None" AutoGenerateColumns="False"
BorderWidth="1px" CellPadding="4"
EnableModelValidation="True" ForeColor="Black" GridLines="Horizontal"
Width="99%" AllowPaging="True" PageSize="500" DataSourceID="SqlDataSource_BCS" >
<Columns>
<asp:TemplateField HeaderText="#">
<ItemTemplate>
<%#Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Att_ID" HeaderText="Att_ID"
SortExpression="Att_ID" />
<asp:BoundField DataField="Emp_FullName" HeaderText="Emp_FullName"
SortExpression="Emp_FullName" />
<asp:BoundField DataField="Att_Desc" HeaderText="Att_Desc"
SortExpression="Att_Desc" />
<asp:BoundField DataField="Att_Type" HeaderText="Att_Type"
SortExpression="Att_Type" />
<asp:BoundField DataField="Att_Date" HeaderText="Att_Date"
SortExpression="Att_Date" />
<asp:templatefield HeaderText="Attendance" >
<itemtemplate >
<asp:CheckBox ID="CheckBox_Attendance" runat="server" />
</itemtemplate>
<itemstyle horizontalalign="left" />
</asp:templatefield>
</Columns>
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<HeaderStyle BackColor="White" Font-Bold="True" BorderWidth="0px"/>
<PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BorderStyle="None" />
<SelectedRowStyle BackColor="#CC3333" Font-Bold="True" ForeColor="White" />
</asp:GridView>
I have no idea what is the correct way to do this.
Thanks in advance
You can bind your checkbox directly to the field like so...
<asp:CheckBox ID="CheckBox_Attendance" runat="server" Checked='<%# Eval("Att_type").ToString() = "1" %>' />
Otherwise, handle it directly on your gridview rowdatabound event:
Put the following on your gridview:
<asp:GridView ... OnRowDatabound="dg_RowDataBound">
Change your TemplateField to look like this:
<asp:TemplateField HeaderText="Attendance">
<ItemTemplate>
<asp:HiddenField id="hfType" Value='<%# Eval("Att_Type") %>' />
<asp:CheckBox ID="CheckBox_Attendance" runat="server" />
</ItemTemplate>
<ItemStyle HorizontalAlign="left" />
</asp:TemplateField>
In your code behind
Protected Sub dg_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Dim cbAttendance As Checkbox = e.Row.FindControl("CheckBox_Attendance")
Dim hfType as Hiddenfield = e.Row.FindControl("hfType")
If hfType.Value = "1" Then
cbAttendance.Checked = True
End Sub
Currently I am making a webapp in asp.net. Normally I use a sqlDataSource and enable paging and deleting etc, but I am not able to do that in this case.
I made a GridView and it shows the data perfectly, how ever my RowDelete event doesn't fire
Code GridView: ( only relevant code )
<asp:GridView ID="GridView1"
runat="server"
onpageindexchanging="GridView1_PageIndexChanging"
onrowdeleting="GridView1_RowDeleting">
<Columns>
<asp:TemplateField
HeaderStyle-CssClass="head"
ItemStyle-CssClass="items"
HeaderText="Klant">
<ControlStyle ForeColor="#333333" />
<HeaderStyle CssClass="head"></HeaderStyle>
<ItemStyle CssClass="items" Font-Bold="False" ForeColor="#494C50" ></ItemStyle>
<ItemTemplate>
<asp:LinkButton ID="klant" runat="server"
Text='<%#Eval("Bedrijf") %>'
PostBackUrl='<%# "klant_wijzigen.aspx?Klant_ID="+Eval("Klant_ID").ToString()%>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField
HeaderStyle-CssClass="head"
ItemStyle-CssClass="items"
HeaderText="Categorie">
<ItemTemplate>
<asp:LinkButton ID="categorie" runat="server"
Text='<%#Eval("Categorie") %>'
PostBackUrl='<%# "cat_wijzigen.aspx?Cat_ID="+Eval("Cat_ID").ToString()%>'>
</asp:LinkButton>
</ItemTemplate>
<ControlStyle ForeColor="#333333" />
<HeaderStyle CssClass="head"></HeaderStyle>
<ItemStyle CssClass="items" Font-Bold="false" ></ItemStyle>
</asp:TemplateField>
<asp:BoundField
DataField="Website"
headertext="Website"
HeaderStyle-CssClass="head"
ItemStyle-CssClass="items">
<HeaderStyle CssClass="head"></HeaderStyle>
<ItemStyle CssClass="items"></ItemStyle>
</asp:BoundField>
<asp:BoundField
HeaderStyle-CssClass="head"
DataField="Titel"
headertext="Titel"
ItemStyle-CssClass="items"
>
<HeaderStyle CssClass="head"></HeaderStyle>
<ItemStyle CssClass="items"></ItemStyle>
</asp:BoundField>
<asp:TemplateField
HeaderStyle-CssClass="head2"
ItemStyle-CssClass="items2">
<ItemTemplate>
<asp:Button ID="LinkButton1"
runat="server"
CausesValidation="False"
CommandName="Delete" Text="Delete"
CssClass="verwijder"
OnClientClick="return confirm
('Weet je zeker dat je het project wilt verwijderen?')">
</asp:Button>
<asp:Button ID="project" runat="server"
Text="Details"
CssClass="details"
PostBackUrl='<%#"Details.aspx?ID="+Eval("ID").ToString()%>'
/>
</ItemTemplate>
<HeaderStyle CssClass="head2"></HeaderStyle>
<ItemStyle CssClass="items2"></ItemStyle>
</asp:TemplateField>
</Columns>
<HeaderStyle CssClass="head"></HeaderStyle>
<AlternatingRowStyle BackColor="#e1e3e9" />
</asp:GridView>
As you can see they are all bounded. The delete button is a LinkButtton
And this is my script:
Protected Sub Gridview1_RowDeleting(ByVal sender As Object, ByVal e As GridViewDeleteEventArgs)
GridView1.DeleteRow(e.RowIndex)
GridView1.DataBind()
End Sub
I bind my GridView like this: I have made 2 seperate SqlDataSources with 2 different Select Queries. Based on on the SelectedValue of my dropdownlist selects the SqlDataSource:
Code
Public Sub Wop() 'Here I set the IF statement.
If DropDownList1.SelectedValue = 0 Then
GridView1.DataSource = SqlDataSource4()
Else
GridView1.DataSource = SqlDataSource2()
End If
GridView1.DataBind()
End Sub
Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Wop() `Here is were I call the IF statement.
End Sub
Any clue would be appreciated.
NOTE
I must say I am not writing in C#!
You look like you're calling DeleteRow from within your RowDeleting event. That doesn't make any sense since I would imagine that RowDeleting is not raised until DeleteRow is called.
Edit:
From MSDN:
Use the DeleteRow method to programmatically delete the record at the
specified index from the data source. This method is commonly used
when you need to delete a record from outside of the GridView control,
such as from a different control on the page. Calling this method also
raises the RowDeleted and RowDeleting events.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.deleterow.aspx
my question is simple, how do i create a custom save and update button for records entered in a detail view. I dont want to use the ones given. thanks a lot.
You have a couple of options. One is the OnItemCommand and you'll roll your own commands.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.itemcommand.aspx
The easier way is to use the OnItemInserted and OnItemUpdating events. Just send the Insert or Update commands instead as appropriate and you can use easier EventArgs
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.iteminserting.aspx
<http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.itemupdating.aspx
From these pages, basically what you'll do is capture a command from a button in your DetailsView.
Custom "Add" commamnd with ItemCommand
Sub CustomerDetailView_ItemCommand(ByVal sender As Object, ByVal e As DetailsViewCommandEventArgs)
' Use the CommandName property to determine which button
' was clicked.
If e.CommandName = "Add" Then
' Do your work here if Add Contact is clicked
End If
End Sub
Easier built in Insert command with ItemInserting
Sub CustomerDetailView_ItemInserting((ByVal sender As Object, ByVal e As DetailsViewInsertEventArgs)
' Access the actual rows with
Some variable1 = e.Values("CustomerID")
Some variable2 = e.Values("CompanyName")
Some variable3 = e.Values("City")
' Do something with them
End Sub
Code front
<asp:DetailsView ID="CustomerDetailView"
DataSourceID="DetailsViewSource"
AutoGenerateRows="false"
DataKeyNames="CustomerID"
AllowPaging="true"
OnItemCommand="CustomerDetailView_ItemCommand"
OnItemInserting="CustomerDetailView_ItemInserting"
OnItemUpdating="CustomerDetailView_ItemUpdating"
runat="server">
<FieldHeaderStyle BackColor="Navy" ForeColor="White" />
<Fields>
<asp:BoundField DataField="CustomerID" HeaderText="Store ID" />
<asp:BoundField DataField="CompanyName" HeaderText="Store Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:TemplateField HeaderText="Name">
<InsertItemTemplate>
<asp:Button ID="btAddContact" runat="server" Text="Add Contact" CommandName="Add" />
Or
<asp:Button ID="btAddContact" runat="server" Text="Add Contact" CommandName="Insert" />
</InsertItemTemplate>
<EditItemTemplate>
<asp:Button ID="btAddContact" runat="server" Text="Save Contact" CommandName="Update" />
</EditItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
You can use any button that implements the IButtonControl interface. The key is to set the CommandName correctly. Hopefully this will give you the freedom to style your button the way you need to.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.commandname.aspx
You can find a list of the relevant command names here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemcommand.aspx
<asp:ImageButton runat="server" ... CommandName="Save" />
<asp:LinkButton runat="server" ... CommandName="Update" />
We have the following code in an UpdatePanel.
<asp:UpdatePanel
ID="UpdatePanelSearch"
runat="server"
UpdateMode="Conditional">
<ContentTemplate>
<p>Parent Search:
<asp:TextBox ID="TextBoxSearch" runat="server" Width="207px"></asp:TextBox>
<asp:Button ID="ButtonSearch" runat="server" Text="Search" />
</p>
</ContentTemplate>
</asp:UpdatePanel>
The code in the VB file looks like this to handle clicking the Search button so a GridView will display data based on the value entered into the TextBox.
The GridView is also in a separate UpdatePanel:
Protected Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
GridViewParentsSummary.DataSource = theTableAdapter.GetData(strSearchText)
End Sub
We would like to create a trigger to update the GridView if that is the correct thing to do here.
Here is the GridView:
<ContentTemplate>
<asp:GridView
ID="GridViewParentsSummary"
runat="server"
AllowPaging="True"
AllowSorting="True"
AutoGenerateColumns="False"
DataKeyNames="ID"
PageSize="3"
>
<Columns>
<asp:BoundField
DataField="FatherName"
HeaderText="Father's Name"
SortExpression="FatherName" />
<asp:BoundField
DataField="MotherName"
HeaderText="Mother's Name"
SortExpression="MotherName" />
<asp:ButtonField
ButtonType="Button"
CommandName="Select"
Text="Select This Parent" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Can you show the needed code required to make the correct trigger that will refresh the GridView?
If the GridView is in another UpdatePanel it should also update when another UpdatePanel updates. By default, the UpdatePanel.UpdateMode property is set to Always and this will cause all UpdatePanel in page to refresh.
However, this is not always the desired behavior so many time you'll change it to Conditional which means that the UpdatePanel will be refreshed only if one of its triggers was fired. In that case, you need to add this line in the ButtonSearch_Click method:
gridUpdatePanel.Update() 'assuming gridUpdatePanel is the UpdatePanel with the grid
for more information about the UpdateMode property look here:
http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.updatemode.aspx
I have a Details View that has a file upload field in it. When I fill out the information and upload a file (I have tried multiple files ranging from 9k to 6.8MB) all of the information (text fields) submit fine, but the uploaded file is always returning a false when I check the HasFile and always returns String.Empty when I check the file name.
Am I doing something wrong? The details view is in a Panel and Not an Update Panel
<asp:Panel ID="pnlUpdate" runat="server"
Visible="false">
<h4 runat="server" id="h2SubCaption">Person Details</h4>
<asp:DetailsView ID="dvAssignment"
runat="server"
AutoGenerateRows="false"
Width="100%"
SkinID="SampleDetailsView"
CssSelectorClass="PrettyDetailsView"
DataKeyNames="guidMemberId"
DefaultMode="Edit"
OnItemUpdating="dvAssignment_ItemUpdating"
OnModeChanging="dvAssignment_ModeChanging"
AutoGenerateEditButton="True" >
<Fields>
<asp:TemplateField HeaderText="Nomination Letter">
<EditItemTemplate>
<asp:FileUpload runat="server" ID="fileuploadNomination" />
</EditItemTemplate>
</asp:TemplateField> .....
Code Behind:
FileUpload _nomination = (FileUpload)dv.FindControl("fileuploadNomination");
byte[] nominationByte = null;
if (_nomination.FileName != string.Empty)
nominationByte = _nomination.FileBytes;
//if(_nomination.HasFile)
//nominationByte = _nomination.FileBytes;
EDIT
I added a Page_Load call and it looks as if the page is posting back when I click the Auto Generated Update Button for the DetailsView. This postback is probably clearing out my FileUpload field. Any ideas on how to get around it?
Edit #2 I have now put an update panel around the DetailsView and set the postback trigger the DetailsView (see below) and it still is not working, it seems to be clearing the upload control prior to submitting.
<asp:UpdatePanel ID="updatePnl" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Panel ID="pnlUpdate" runat="server"
Visible="false">
<h4 runat="server" id="h2SubCaption">Person Details</h4>
<asp:DetailsView ID="dvAssignment"
runat="server"
AutoGenerateRows="false"
Width="100%"
SkinID="SampleDetailsView"
CssSelectorClass="PrettyDetailsView"
DataKeyNames="guidMemberId"
DefaultMode="Edit"
OnItemUpdating="dvAssignment_ItemUpdating"
OnModeChanging="dvAssignment_ModeChanging"
AutoGenerateEditButton="True" >
<FieldHeaderStyle Font-Bold="True" Width="150px" />
<Fields>
<asp:FileUpload runat="server" ID="fileuploadNomination" />
</EditItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView >
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="dvAssignment" />
</Triggers>
</asp:UpdatePanel>
Gridview Code as requested
<asp:GridView ID="gvQuality"
runat="server"
AutoGenerateColumns="False"
Width="100%"
DataKeyNames="guidMemberId"
CssSelectorClass="PrettyGridView"
SkinID="SampleGridView"
OnSelectedIndexChanged="gvQuality_SelectedIndexChanged"
onrowdatabound="gvQuality_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btnViewDetails" runat="server" Text="Edit" CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
a few bound fields are after this (first name, last name, etc)
protected void gvQuality_SelectedIndexChanged(object sender, EventArgs e)
{
Guid guidMemberId = (Guid)gvQuality.SelectedDataKey.Values["guidMemberId"];
PortalDataContext db = new PortalDataContext(AuthenticatedUser.ConnectionString);
h2SubCaption.InnerText = "Update Person";
dvAssignment.ChangeMode(DetailsViewMode.Edit);
dvAssignment.DataSource = LINQ Query Here
dvAssignment.DataBind();
}
Everyone, Thanks for all of the help but I figured it out. I had to set the Page.Form.Enctype = "multipart/form-data.
Here is the code for it to work!
protected void Page_Load(object sender, EventArgs e)
{
this.Page.Form.Enctype = "multipart/form-data";
}
I'm sorry if this is a dumb answer but I usually use on gridviews the selectedindexchanging to capture current row values. Have you tried that instead of the selectedindexchanged?
you can try
Request.Files[0] get the upload file
Make sure you only have one <form> on the same page.