i created a web application wherein i used the onrowcommand and created the handler in code behind, now i have a button inside the emptytemplate, whenever i click the button, my onRowCommand is not executed. Below is my code.
<asp:GridView ID="grdExternalLinkSection1" runat="server" Width="100%" AutoGenerateColumns="false" CellPadding="5" OnRowCommand="grdExternalLinkSection_RowCommand">
<EmptyDataTemplate>
External Link Title
<asp:TextBox ID="txtExternalLinkTitleEmptySection1" runat="server"></asp:TextBox>
External Link Url
<asp:TextBox ID="txtExternalLinkUrlEmptySection1" runat="server"></asp:TextBox>
<asp:Button ID="btnExternalLinkEmptySection1" runat="server" Text="Add" CommandArgument="1" CommandName="headernew" style="padding:3px; width:56px;" />
</EmptyDataTemplate>
</asp:GridView>
there are more fields but this is what i am talking about. and here is my code behind handler for the RowCommand Event.
protected void grdExternalLinkSection_RowCommand(object sender, GridViewCommandEventArgs e)
{
Response.Write("welcome");
}
it never excutes the handler, and below is my page directive:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="NewsletterASPVersion.ascx.cs" Inherits="RWO_Controls_NewsletterASPVersion" %>
this worked once, and after thereafter never working. does anyone have any idea what could be causing this.
There are two possible traps that you might have fallen into:
You are rebinding the GridView to it's DataSource on every postback.
So always check:
if(!IsPostBack)BindGrid();
You are not calling grdExternalLinkSection1.DataBind() when the DataSource is empty
But then you would not see the EmptyDataTemplate at all. So i guess that you've fallen into the first trap.
Related
I am new to ASP.Net and I am confused about the way a GridView control works inside an UpdatePanel.
I have read the documentation here which states "By default, any postback control inside an UpdatePanel control causes an asynchronous postback and refreshes the panel's content." yet, when I place a GridView and a Button control inside the element, unless the button has a defined OnClick event to do grid1.DataBind();, the grid will NOT refresh its data. Also, I have tried by specifying an AsyncPostBackTrigger on the UpdatePanel for the Button, but again I got the same behaviour. Now, I noticed that the UpdatePanel DOES refresh when I press a Button without OnClick event, however the GridView inside it does not. Please can you shed some light on this? Must I always have that call to code behind to explicitly refresh it?
My connection string in Web.Config
<connectionStrings>
<add name="myConnectionString"
connectionString="Data Source=XXXXX;Initial Catalog=XXXX;Persist Security Info=True;User ID=XXXXX;Password=XXXXX"
providerName="System.Data.SqlClient" />
</connectionStrings>
My Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="EmptyWebApp.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"> <title></title> </head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager" runat="server" EnablePartialRendering="true" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="grid1" runat="server" DataSourceID="SQLDevelopment" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" />
<asp:BoundField DataField="Date" HeaderText="Date" SortExpression="Date" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SQLDevelopment" runat="server"
ConnectionString="<%$ ConnectionStrings:myConnectionString %>"
SelectCommand="SELECT * FROM [TestTableA]"></asp:SqlDataSource>
<%=DateTime.Now.ToString()%> <br />
<asp:Button ID="btnRefresh" runat="server" Text="Refresh without C# event"/>
<asp:Button ID="btnRefresh1" runat="server" Text="Refresh with C# event" OnClick="btnRefresh1_Click"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form></body><html>
My Code behind for btnRefresh1
protected void btnRefresh1_Click(object sender, EventArgs e)
{
grid1.DataBind();
}
THANK YOU
There is nothing wrong with update-panel code - issue is that grid-view will not demand the data again from data-source on post-back. Rather, it will use view-state to load the corresponding data.
However, call to DataBind will force grid-view to get the data from data source again thereby refreshing it (or you may try disabling the view-state for grid view) - see documentation for the method - comments within example code says the same.
In case, you do not want to add DataBind call in refresh button, you can do the same in Page_Load - thereby refreshing the grid on every post-back (regardless the control that has caused it).
Use .DataBind() in the script for your gridview (ie gridview1.DataBind();). This is just rebinds the data to the gridview that was already set in your data source.
<asp:GridView ID="grid1" runat="server" DataSourceID="SQLDevelopment" AutoGenerateColumns="False">
See MSDN for more info.
Or allow the ScriptManager to do it all for you in one line of code!
ScriptManager.GetCurrent(this).RegisterPostBackControl(ButtonSubmit);
Replace the ButtonSubmit with your own control.
I have a page where guests can be selected.
This page contains an update panel, within the update panel there is a wizard control and in the wizard control there is a gridview (Panel-> Update Panel -> wizard control -> gridview)
Now the paging doesn't work well, I searched the internet for answers but I didn't find the right answer. I use custom paging.
When I want to change the pagenumber (to the second or last page) it works fine. But when I want to select a row or go to another page, the gridview doesn't work correct. When I select A row on the second or last page (other page's don't work) the selected guest (item) is always one of the first page. When I want change to another page (from the second or last page) it doesn't work and stays on the selected page.
Is there a way to solve this problem?
part of the code:
<asp:Panel ID="PnlRe" Style="display: none; ... >
<asp:UpdatePanel ID="UpdtPnlDetail" runat="server" UpdateMode="Conditional">
<ContentTemplate>
...
<asp:Wizard ID="wzd" runat="server" ... >
...
<asp:WizardStep ID="WizardStep3" runat="server" Title="Naam">
...
<asp:Gridview ID="Gridview1" runat="server" AutoGenerateColumns="False"
DataKeyNames="GastID,Versie" DataSourceID="odsGasten" EmptyDataText="...."
OnRowCommand="Gridview1_RowCommand" OnPageIndexChanging="Gridview1_PageIndexChanging"
OnPageSizeChanging="Gridview1_PageSizeChanging" OnSearching="Gridview1_Searching"
OnSorting="Gridview1_Sorting" OnRowDataBound="Gridview1_RowDataBound"
CausesValidation="False" meta:resourcekey="..." PagerType="Custom"
ShowFilter="True" ShowInsertRecord="True" ShowPageSizer="True" UseSubmitBehaviour="False">
<Columns>
<asp:TemplateField ShowHeader="False" meta:resourcekey="...">
<ItemTemplate>
<asp:ImageButton runat="server" CommandName="Select" CausesValidation="False" SkinID="uprowbutton"
ToolTip="..." ID="ImgBtnSelect" meta:resourcekey="...">
</asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
... Boundfields ...
</Columns>
</asp:Gridview>
...
</asp:WizardStep>
...
</asp:Wizard>
</ContentTemplate>
</asp:UpdatePanel>
protected void Gridview1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
this.odsGasten.FilterExpression = searchText;
this.Gridview1.DataBind();
this.UpdtPnlDetail.Update();
}
there is a tricky way to achieve this, you have to manipulate your data source.
for example if you are using a datatable you have to select first ten elements of dt and bind it to grid, and when next button is clicked get next ten elements of dt and bind it to gridview. this will make your task easy and will get more performance for your page.
I can see that this.GridView1.DataBind() is called in GridView1_PageIndexChanging, but where is the currentPageIndex stored and updated with the page index you want to navigate to and when in the process is it happening?
Sounds to me like you have a viewstate problem.
You need to make sure that between Init and Load you have the grid's source set, either from viewstate or from a new bind-ing.
I want to set the textbox contol located in the panel control via code
I know to retrieve the inputted value in the textbox control:
string myVal = Request.Form["txtResult"];
I want to set the txtResult.text = "some text";
makeup snippet:
<asp:Panel ID="Panel1" runat="server" Style="display: none" Width="233px">
<asp:TextBox ID="txtResult" runat="server" AutoPostBack="True"></asp:TextBox>
<br />
<div align="center">
<asp:Button ID="OkButton" runat="server" Text="OK" />
<asp:Button ID="CancelButton" runat="server" Text="Cancel" />
</div>
</asp:Panel>
txtResult is not available within code, I tried to see if it is available in the page_load, it's not
texReults was a typo, its txtResult, I updated the ID
the intellisense does not recognize any cntr by the name txtResult
its a new web application and the panel visibility=True
maybee this wil help, above the snipet, I use ScriptManager from the AJAX Exstension
I am aware of he Asnchronius affects, partial potback, etc.
It's a managed control, you should be able to set it on the Page_Load event:
protected void Page_Load(object sender, System.EventArgs e)
{
txtResult.Text = "some text";
}
Update: Based on your update, there are a couple of things that you would need to check:
Spelling: Are you sure you're spelling the control name correctly?
Its ID in your code is "txtResults", but you're referencing it as
"txtResult".
Designer: Did you copy the aspx page or bypass VS in some way for this page? If so check the .designer file for the reference to the control: i.e. "Page1.aspx.designer.cs"
Visibility: Is the Panel control's visibility set to true? If not, then it won't render the controls that are contained within it.
Update 2: If you're doing this through scriptmanager, then I highly recommend that you read through this: http://www.wrox.com/WileyCDA/Section/Using-the-ASP-NET-AJAX-ScriptManager.id-305492.html
I have a repeater with a RadioButtonList inside the ItemTemplate, but when the RadioButtonList.OnSelectedIndexChanged event fires it generates a full postback. What have I done wrong in my code below? How can I get the OnSelectedIndexChanged to generate an Async Postback?
<asp:UpdatePanel runat="server" ID="UpdatePanel2">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="sqlOptions">
<ItemTemplate>
<asp:UpdatePanel runat="server" ID="pnlA">
<ContentTemplate>
<strong>
<%# Eval("Name") %></strong><br />
<asp:RadioButtonList ID="RadioButtonList1"
DataSourceID="sqlOptionValues" runat="server"
DataTextField="id" DataValueField="Id" AutoPostBack="true"
OnSelectedIndexChanged="LoadPrice"
ValidationGroup="options" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ForeColor="Red" runat="server"
ControlToValidate="RadioButtonList1"
ErrorMessage="Required Field"
ValidationGroup="options" />
<asp:SqlDataSource ID="sqlOptionValues" runat="server"
ConnectionString="<%$ ConnectionStrings:
ConnectionString6 %>"
SelectCommand='<%# "SELECT DISTINCT OptionValue.Name,
OptionValue.Id FROM CombinationDetail
INNER JOIN OptionValue
ON CombinationDetail.OptionValueId = OptionValue.Id
WHERE (OptionValue.OptionId =" +
Eval("Id") + ")" %>'>
</asp:SqlDataSource>
<br />
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
Many thanks for any help :)
This is a real-world use case. I have a page with Repeaters, Ajax Accordions inside of other Accordions, Update Panels inside other Update panels, you name it. The page works great, except when I want to update one of the Accordion panels with my RadioButtonList (RBL). Even with the RBL inside an update panel, it causes a postback of the entire page. I tried everything. I finally realized it wasn't me when I noticed my buttons would work just fine. I figure it must be a bug in either the framework or the Ajax Control Toolkit. I did find people reference this link all over the web (http://blog.smarx.com/posts/the-case-of-the-radiobuttonlist-half-trigger.aspx), but this link from 2007 is dead now and probably no longer applicable, so that's no help.
What I ended up doing was going with what works - that submit button. All I did was add an onclick attribute to the RBL to call a hidden button. Now you don't want to set the button to Visible=false because then the button won't appear in the generated markup. Instead, set the button's style to display:none; so that no one will see this hack, because yes, that's what this workaround is - it's a hack, but simple and just as effective as what you'd expect. Don't forget to remove the Autopostback="True" from your RBL.
CAVEAT: Because I'm using a hacked button for the onclick event, it's possible for the user to click in the area of the RBL, but not actually select an item. When this happens, our onclick triggers an AsyncPostBack and the codebehind logic will be processed, so please keep that in mind. To give you an idea of what I mean: all the Page_Load() events will be called, but rbl_Questions_SelectedIndexChanged() won't be if they happen to click in the area of the RBL without actually selecting an item. For my purposes this causes no issues in my logic and has no effect on the user.
Here's the Code:
Somewhere In the .Aspx Page:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:RadioButtonList ID="rbl_Questions" runat="server"
OnSelectedIndexChanged="rbl_Questions_SelectedIndexChanged">
</asp:RadioButtonList>
<asp:Button ID="btn_rbl_Questions" runat="server" style="display:none;"/>
<asp:Label ID="lbl_Result" runat="server" Text="" Visible="false">
</asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
In the Page_Load() event:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
//Instead of using the AutoPostback of the RBL, use this instead.
rbl_Questions.Attributes.Add("onclick",
"document.getElementById('"
+ btn_rbl_Questions.ClientID
+ "').click();");
//Bind your RBL to a DataSource, add items programmatically,
// or add them in the aspx markup.
}
}
In the rbl_Questions_SelectedIndexChanged() event:
protected void rbl_Questions_SelectedIndexChanged(object sender, EventArgs e)
{
//Your code here.
//My code unhid the lbl_Result control and set its text value.
}
Update 05/24/2011
The above "hack" is no longer necessary (I am leaving it above since this was marked as the answer by the author). I have found the best way to do this, thanks to this SO Answer:
Updatepanel gives full postback instead of asyncpostback
The code is much simpler now, just remove what I put in the Page_Load() method and remove the Button I used in the Aspx page and add ClientIDMode="AutoID" and AutoPostBack="True" to the control you want the UpdatePanel to capture.
Somewhere In the .Aspx Page:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:RadioButtonList ID="rbl_Questions" runat="server"
ClientIDMode="AutoID" AutoPostBack="true"
OnSelectedIndexChanged="rbl_Questions_SelectedIndexChanged">
</asp:RadioButtonList>
<asp:Label ID="lbl_Result" runat="server" Text="" Visible="false">
</asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
MS changed how ClientID's are generated in .net 4.0 from "AutoID" to "Predictable" and I guess the ScriptManager or UpdatePanel's weren't updated correctly to use it. I can't find documentation on why that is anywhere or if it was left that way by design.
I seriously don't miss winforms.
Try this:
<asp:UpdatePanel runat="server" UpdateMode="Conditional" ID="pnlA">
You'll also need to setup
<Triggers>
//radio buttons
</Triggers>
Not sure how you'll do that since it's a dynamically built list.
ASCX File:
<asp:datagrid runat="server" id="gridFormFields" datakeyfield="FieldID"
autogeneratecolumns="False"
onitemcommand="gridFormFields_ItemCommand" onitemdatabound="gridFormFields_ItemDataBound">
<columns>
<asp:templatecolumn>
<itemtemplate>
<asp:imagebutton runat="server" id="buttonMoveUpFormField" resourcekey="buttonMoveUpFormField"
commandname="Item" commandargument="MoveUp" imageurl="~/images/up.gif" />
</itemtemplate>
</asp:templatecolumn>
<asp:templatecolumn>
<itemtemplate>
<asp:imagebutton runat="server" id="buttonMoveDownFormField" resourcekey="buttonMoveDownFormField"
commandname="Item" commandargument="MoveDown" imageurl="~/images/dn.gif" />
</itemtemplate>
</asp:templatecolumn>
</columns>
Code behind:
protected void gridFormFields_ItemDataBound(object sender, DataGridItemEventArgs e)
{
(e.Item.FindControl("buttonMoveUpFormField") as ImageButton)
.Visible = gridFormFields.Items.Count > 1 && e.Item.ItemIndex > 0;
(e.Item.FindControl("buttonMoveDownFormField") as ImageButton)
.Visible = gridFormFields.Items.Count > 1 && e.Item.ItemIndex < gridFormFields.Items.Count - 1;
}
In the code behind, the Control returned by FindControl is null. Why?
How can I access the buttonMoveUpFormField and buttonMoveDownFormField controls?
From the code behind, is it possible to access controls which are declared in the ItemTemplate section of the TemplateColumn section of a DataGrid?
Because you need to add code to include "Item" and "AlternatingItem" and exclude all other types, before you try to find that control.
if (e.Item.Type == ...
You can certainly access the controls that are within the ItemTemplate section. I'm dealing with a similar issue. One thing that I've found is, depending what is calling your "gridFormFields_ItemDataBound", you may not have access to those controls yet.
I know that in my instance, I've got an "ItemTemplate" and an "EditItemTemplate", when I click edit, it fires an event "RowEditing" before it is actually switched to "Edit Mode", so the control will not be there yet. I do though have access to the controls in "RowUpdating" which is fired when I click save in the edit mode.
Maybe this helps? For example, your "OnDataBound" might be the event that is trying to access your controls, but you may not have access to them on databound?
Just a thought. I'll edit this if I get any further on mine.