UpdatePanel with GridView with LinkButton with Image Causes Full Postback - asp.net

So this might be a fairly specific issue but I figured I'd post it since I spent hours struggling with it before I was able to determine the cause.
<asp:GridView ID="gvAttachments" DataKeyNames="UploadedID" AutoGenerateColumns="false" OnSelectedIndexChanged="gvAttachments_SelectedIndexChanged" runat="server">
<EmptyDataTemplate>There are no attachments associated to this email template.</EmptyDataTemplate>
<Columns>
<asp:TemplateField ItemStyle-Width="100%">
<ItemTemplate>
<asp:LinkButton CommandName="Select" runat="server"><img src="/images/icons/trashcan.png" style="border: none;" /></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In the ItemTemplate of the TemplateField of the GridView I have a LinkButton with an image inside of it. Normally I do this when I have an image with some text next to it but this time, for whatever reason, I just have the image. This causes the UpdatePanel to always do a full postback.

Instead of changing the markup, you can goto web.config and specify ClientIDMode="Auto" in the pages tag.
Reason why UpdatePanel behaving like this is because the ClientIDMode is getting generated will be too long for UpdatePanel to register. So the ClientID got truncated in middle and such control will be treated like unregistered Control.
For more information read the following:
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode.aspx

Change the LinkButton to be an ImageButton and the problem is solved.
<asp:ImageButton ImageUrl="/images/icons/trashcan.png" Style="border: none;" CommandName="Select" runat="server" />

Above solutions also work, But There is one more thing to check. Check form tag for your page. If id attribute is missing, you will get same issue.
If you form tag is as given below (without id), you will get issue:
<form runat="server">
<!-- your page markup -->
</form>
Please add id, as given below:
<form id="form1" runat="server">
<!-- your page markup -->
</form>
You will not need to update ClientIDMode in web.config or page or control.
You will not need to change your linkbutton in markup.
You will not need to register control for asynch postback from code behind.

Related

I have one issue for ViewState

What is the meaning of EnableViewState="false" and EnableViewState="true"?
I Know EnableViewState="false" = turn Off the ViewState and also EnableViewState="true" = turn On the ViewState
But What is the difference between EnableViewState="false" and EnableViewState="true" ?
I tried this code:
<form runat="server">
<asp:TextBox ID="TextBox1" EnableViewState="true" runat="server">
</asp:TextBox><asp:Button ID="Button1" runat="server" Text="Button" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
I am really confused.
When I used EnableViewState="true", I entered some values in textbox and click my button .Now the value is here in the textbox . Its same process when i set EnableViewState="false".
So What happens when EnableViewState="true" and EnableViewState="false" ?
Texbox Doesnt Use Viewstate here is the link to explain all Link Explain
Generally you should use EnableViewState="false" on all controls on the asp.net page. The viewstate of a control is most commonly needed when you want to preserve some visual appearance of the control itself. E.g. if you change the background color of control and you want to persist that across postbacks use EnableViewState="true".
Not all controls are affected by view state. The controls that implement IEventHandler or IDataHandler will not get affected on page postback if view state is disabled.
Textbox is one such control. If you want to see the effect in your code. Try setting the label value at run time on postback like on Click of button and check the results
ViewState is used to persist properties of a control that are set server-side.
So, to take a contrived example, if you do something like the following in Page_Load:
if (!IsPostBack)
{
TextBox1.ForeColor = ...;
}
then the color you set will be preserved across postbacks in ViewState, if it is enabled.

Textbox losing data within HeaderTemplate on Postback in ASP.Net

I have a ASP.Net GridView and I build the column collection myself. Within the column collection I have a HeaderTemplate and within there I have a textbox which I use to filter the records in the grid.
When I enter text within this textbox and perform an action on the grid which causes a postback (i.e. changing the page) I lose the text within my textbox.
Anybody got any ideas as to why this data is lost?
My ASP code for the header template is below:
<HeaderTemplate>
<asp:Label ID="Label1" Text="Number" runat="server" />
<asp:TextBox ID="textBoxNumberFilter" runat="server" />
<asp:ImageButton ID="buttonFilterNumber" runat="server" OnClick="buttonFilters_Click" />
</HeaderTemplate>
Thanks in advance. I'm using ASP.Net 4.0
I think this might help.
http://www.codeproject.com/Articles/38714/How-To-Perpetuate-Dynamic-Controls-Between-Page-Vi

Cannot remove viewstate hidden field

I have a massive viewstate hidden field that is causing my application to be unworkable. I have tried:
EnableViewState="false" on every control
EnableViewState="false" in page directive
Page.EnableViewState = false in Page_Init
<pages enableViewState="false" /> in web.config
The page causing the issue has a single GridView which I want to render once only, so I don't ever need the viewstate.
I examined the hidden field using this tool, and there is apparently hardly any info in it (since I disabled the property in every control probably). For some reason though, the page insists on including a hidden field that is thousands and thousands of lines long.
How can I get rid of this field (or reduce it to a usable size) for good?
Here is an exert from the offending GridView:
<asp:GridView ID="MyGrid" runat="server" AutoGenerateColumns="False"
EnableModelValidation="True" EnableViewState="False"
CssClass="my-report">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<span title='title' class="abbr">My ID</span>
</HeaderTemplate>
<ItemTemplate>
<%# Eval("my_id") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<span title='title2' class="abbr">Second col heading</span>
</HeaderTemplate>
<ItemTemplate>
<asp:ListView ID="MyListView" runat="server" EnableViewState="False">
<LayoutTemplate>
<ul>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" EnableViewState="False" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li><%# Eval("field_2")%></li>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The hidden field you see on the page is not only for ViewState, it also contains the ControlState. There is no way to disable the control state so you'll need to find a way to live with it. How many items the grid is displaying?
As a last option you may consider compressing generated viewstate field.
Here you have an MSDN article explaining how ControlState works
If your GridView is non-interactive (that is, it doesn't contain any child controls that post back), then you can reduce the size of view state by waiting until the page's Render method is called to bind the grid:
Protected Overrides Sub Render(writer As HtmlTextWriter)
MyGrid.DataSource = ...
MyGrid.DataBind()
MyBase.Render(writer)
End Sub
In case anyone has a similar problem, it was occuring because I had a ListView inside each row of the grid. I replaced the ListView with a Repeater and the viewstate is no longer a problem.
Another option is to use Flesk.ViewState something.
It can put the viewstate on files, compress it, session, etc.
Like the others say, sometimes is inevitable in ASPNET to live with ViewState.
Thats why your best option is to move to MVC :)

ASP.NET Webforms UpdatePanel duplicate contents

I've been handed a huge Webforms project which I'm trying to understand, and I have a problem where an Update Panel is duplicating a lot of its content. The aspx code for the panel is huge, hundreds of lines long, but it basically looks like this simple example, only with lots more asp:TextBox and asp:ListBox.
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true" RenderMode="Block" UpdateMode="Conditional">
<ContentTemplate>
<div><table><tbody><tr><td>
<label>Search</label><asp:TextBox ID="Search" runat="server" />
<asp:LinkButton runat="server" OnClick="find_Click" >Find</asp:LinkButton>
</td></tr></tbody></table></div>
<div id="a"><table><tbody><tr><td>
<label>Result</label><asp:TextBox ID="Result" runat="server" />
</td></tr></tbody></table></div>
</ContentTemplate>
</asp:UpdatePanel>
and code behind like this.
public void find_Click(Object sender, EventArgs e)
{
Result.Text = "oranges";
}
When you click the LinkButton, I would expect to see in the result the <div id="a"> section, but with the text 'oranges' in the TextBox. What you actually get is <div id="a"> with 'oranges', followed by the original <div id="a"> with the empty TextBox. The worst bit is that it doesn't do it in this simple example, nor even in a page that I created that had all the original asp:TextBox and asp:ListBox but filled with dummy data. Can anyone point me to any good ways of approaching this problem?
Another solution would be to make sure all HTML tags are closed inside the asp:UpdatePanel. In my case, I've got the open header tag placed in the Site.Master file (outside of UpdatePanel control) and the closing header tag inside the UpdatePanel control (on aspx page). Because of that, every time the UpdatePanel postbacks it recreates the closing header tag again causing the content to be duplicated. After I placed the closing tag into Site.Master file, everything worked beautifully.
You might have already tried this, but in the actual problem page, is it possible to remove as many server controls out of the updatepanel and just leave in offending textbox and then see what happens? I'm guessing you'll probably have to comment out alot of .cs/.vb code, which can be a pain.
Also try removing the updatepanel and see what happens.
Some serious refactoring later, it now looks like (a very bloated version of) this.
<div><table><tbody><tr><td>
<label>Search</label><asp:TextBox ID="Search" runat="server" />
<asp:LinkButton runat="server" OnClick="find_Click" >Find</asp:LinkButton>
</td></tr></tbody></table></div>
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true" RenderMode="Block" UpdateMode="Conditional">
<ContentTemplate>
<div id="a"><table><tbody><tr><td>
<label>Result</label><asp:TextBox ID="Result" runat="server" />
</td></tr></tbody></table></div>
</ContentTemplate>
</asp:UpdatePanel>

How to have a link in one placeholder open a ModalPopup in a different placeholder?

I have a page with different placeholders. In one of them, I have a link that I want to open a modal popup in a second placeholder (using the ajaxtoolkit ModalPopupExtender) :
<asp:Content ID="content1" ContentPlaceHolderID="placeholder1" Runat="Server">
<asp:LinkButton ID="link" runat="server" Text="Popup link" />
</asp:Content>
<asp:Content ID="content2" ContentPlaceHolderID="placeholder2" Runat="Server">
<asp:Panel ID="panel" runat="server" Text="Popup content" />
<ajaxToolkit:ModalPopupExtender ID="popup" runat="sever"
TargetControlID="link"
PopupControlID="panel"
/>
</asp:Content>
When doing as above, it fires me an exception, saying that popup cannot find link (which I understand, because they are in two different placeholders).
How can I make this work ? I can think of something find FindControl in the code behind, but I don't really like to use this function, as it is pretty computationally expensive (especially with my nested layout).
One issue is that your TargetControlID and PopupControlIDs are reversed. TargetControlID is the ID of the item that you want to 'Modal Pop', in your case that would be Panel1. The PopupControlID is the ID of the control that would trigger the ModalPopup, in your case that would be "Link"
But you still have a few options if that doesn't work, I have fired a modal located in a different update panel before using the method below. Though not the exact same issue, this workaround may help you (I am assuming you have a script manager on your page).
Create a hidden element in Content2 with ID="hiddenLink"
Set your ModalExtender PopupControlID="hiddenLink"
In the codeBehind for "link" in content1, add an onClick event with the following
ModalPopup1.show()
If you are using updatePanels, this will cause the ModalPopup to display in AJAX fashion without page refresh.But you would still get a full postback worht of data between the client and the server.
Method 2, you could use a javascript function to show to Modal as well. Add a behaviorID="MyModal1" (or whatever you want to call it) to your Modalpopup definition. Then change your link:
<asp:LinkButton ID="link" runat="server" Text="Popup link" OnClientClick="$get('MyModal1').show(); return false;"/>
Note: The return false in the above example prevents the .NET page from performing a postback.

Resources