IGNORE THIS:
I was rebinding the grid in the Onload method.
I have a grid view with some textboxes, which I have to wrap in a UpdatePanel Control. So it looks like this:
<asp:UpdatePanel ID="upDistribution" runat="server" OnLoad="upDistribution_OnLoad">
<ContentTemplate>
<asp:GridView ID="gvDistributions" runat="server" AutoGenerateColumns="false"
OnRowDataBound="gvDistributions_RowDataBound"
CssClass="TallCells ContrastTable MaxWidth LeftHeaders"
GridLines="Both" ShowFooter="True" style="">
<RowStyle HorizontalAlign="Left" />
<EmptyDataTemplate>
No pricing history data found.
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="PriceA">
<ItemTemplate>
<asp:TextBox ID="txtPriceA" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DistPrice">
<ItemTemplate>
<asp:TextBox ID="txtDistPrice" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
There is a button "Save" when I would like to get the value entered for the txtboxes. If there is no UpdatePanel around the GV, i can can easily get the txtbox values like:
((TextBox)gvDistributions.Rows[0].Cells[0].FindControl("txtPriceA")).Text
But when, the GridView is wrapped with UpdatePanel, the above statement returns the value that was set on the page load.
How can I get the value of the text box without getting rid of the updatePanel. I need the update panel, because the number of rows, and dates are dependent on another variable in another user control.
As per my understanding, you should use a trigger for the update panel which is something like below.
<asp:UpdatePanel ...>
<ContentTemplate>
...
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Hope this helps!!
Use your TextBoxes with their AutoPostBack property set True
<asp:TextBox ID="txtPriceA" runat="server" AutoPostBack="True"/>
I was rebinding gridview in the onLoadMethod
Related
After much searching and testing, it's time to ask for opinions.
A GridView inside an Update Panel with a file upload in an EditItemTemplate:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" OnRowUpdating="GridView1_RowUpdating"
OnRowDataBound="GridView1_RowDataBound" OnRowEditing="GridView1_RowEditing"
OnRowCancelingEdit="GridView1_RowCancelingEdit" OnRowCommand="GridView1_RowCommand" >
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="true" >
</asp:CommandField>
<asp:TemplateField HeaderText="Attachment" SortExpression="FileName">
<EditItemTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" /><br />
<asp:Button ID="btnAddAttachment" runat="server" Text="Upload File" CommandName="AddAttachment"
CommandArgument='<%# Bind("ID") %>' />
</EditItemTemplate>
<ItemTemplate>
<a id="ancLink" runat="server" href='<%# "~/Files/" + (DataBinder.Eval(Container.DataItem,"FileName")) %>'
target="_blank">
<asp:Label ID="lblAnchor" runat="server"></asp:Label></a>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
Then for the button in the EditItemTemplate, add the RegisterPostBackControl:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState == DataControlRowState.Edit) || ((e.Row.RowState & DataControlRowState.Edit) > 0))
{
Button btnAddAttachment = (Button)e.Row.FindControl("btnAddAttachment");
AjaxControlToolkit.ToolkitScriptManager ToolkitScriptManager1 = (AjaxControlToolkit.ToolkitScriptManager)Master.FindControl("ToolkitScriptManager1");
ToolkitScriptManager1.RegisterPostBackControl(btnAddAttachment);
}
}
}
The problem is that the RegisterPostBackControl will not work the first time an attempt is made to upload a file. If a user edits the same row again, the second attempt works fine.
Most likely because the RegisterPostBackControl takes effect on the second post back.
Is there a way to have the button have a full postback the first time?
I know there is an easy way for a work around but this defeats the purpose of the UpdatePanel:
<Triggers>
<asp:PostBackTrigger ControlID="GridView1" />
</Triggers>
And since only Admins will have access to editing, setting the PostBackTrigger for the grid in the code behind for only admins is also an option, but once again, defeating the purpose of the Update Panel.
Any suggestions are welcome.
Depending on lots of factors, you could try the updatepannel option:
ChildrenAsTriggers="true"
It may work as a temporary workaround if you need to push something out now.
Based on your code you have the UpdatePanel using the default values so ChildrenAsTriggers is true and UpdateMode is Always, so you should get a full postback every time.
But I don't see you setting the Gridview's DataSourceID so it won't Databind unless you do so somewhere in the code behind. But you would have to be in edit mode initially in order to even find the control you're trying to register. So you need to register the control when you go into edit mode, try finding and registering the control in the gridview RowEditing event
<asp:Timer ID="timer1" runat="server" Interval="1000" OnTick="Timer1_Tick" />
<asp:UpdatePanel runat="server" id="pnlUpdate">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timer1" eventname="Tick"/>
</Triggers>
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" CssClass="table table-hover table-condensed"
GridLines="None" AllowPaging="true" PageSize="20"
OnPageIndexChanging="GridView1_PageIndexChanging">
<Columns>
<asp:BoundField ItemStyle-Width="50%" DataField="Story" HeaderText="Story"/>
<asp:BoundField ItemStyle-Width="15%" ItemStyle-Wrap="false" DataField="AssignedTo" HeaderText="Assigned To"/>
<asp:BoundField ItemStyle-Width="15%" ItemStyle-Wrap="false" DataField="Status" HeaderText="Status"/>
<asp:BoundField ItemStyle-Width="15%" ItemStyle-Wrap="false" DataField="Started" HeaderText="Started"/>
<asp:BoundField ItemStyle-Width="5%" ItemStyle-Wrap="false" DataField="Updated" HeaderText="Updated"/>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Buttonid" runat="server" CommandName="ViewItem" Text="View" BorderStyle="None" BackColor="White"
OnClick="Button_click_event"></asp:Button>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<RowStyle CssClass="cursor-pointer" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Button_click_event won't fire when I have update panel, but it works when it is not in the update panel.
your update panel look like
<asp:UpdatePanel ID="upWall" runat="server" ChildrenAsTriggers="true" UpdateMode="conditional">
<ContentTemplate>
....
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Buttonid" EventName="Click"/>
</Triggers>
Try setting UpdateMode="Conditional" and ChildrenAsTriggers="False" to the UpdatePanel..
<Triggers>
<asp:AsyncPostBackTrigger ControlID="GridView1" />
</Triggers>
Also remove the EventName attribute for your trigger and try again..
Remove the attribute of button click CommandName="ViewItem"
and then try , if not work also add Property of button UseSubmitBehaviour=true
You could solve this in various ways. One way is on rowdatabound in the code behind adding a control that can handle an onclick event, for example a div, and then add a postback handler to your clickable control:
HtmlGenericControl div = (HtmlGenericControl)e.Row.FindControl("Buttonid");
div.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(GridView1, "Select$" + e.Row.RowIndex.ToString()));
Alternatively, I implemented another workaround that works for me:
place a button outside your gridview, but inside the Updatepanel. Also, add a hiddencontrol, where you are going to store the rowindex clicked. Then Add to your template field a 'clickable div' (in which you can put a label for your text), that calls a javascript. Something like this (you can add a display none style to hide the button).:
<asp:Button id="Buttonid" runat="server" OnClick="Button_click_event" />
<asp:HiddenField ID="hdnRowClicked" runat="server" Value="" />
<itemtemplate>
<div onclick="javascript:rowClicked('<%= Buttonid.ClientID %>','<%= hdnRowClicked.ClientID %>', this);">
<asp:Label ID="lblImgDetail" runat="server" Text="+"></asp:Label>
</div>
</itemtemplate>
Then within the javascript function, set the rowindex and call the button to do the postback:
function rowClicked(btnId, hdnRowSelected, lnk) {
var rowIndex = lnk.parentNode.parentNode.rowIndex - 1;
$('#' + hdnRowSelected).val(rowIndex);
$('#' + btnId).click();
}
I want the OnRowCommand event of the GridView to not perform a full postback on a ErrorLinkButton click. So I wrapped the control in an update panel and added an AsyncPostBackTrigger for OnRowCommand:
<asp:GridView ID="DataSourceMappingGridView" runat="server" DataKeyNames="Index" ClientIDMode="Static" OnRowCommand="DataSourceMappingGridView_RowCommand" OnRowDataBound="DataSourceMappingGridView_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:UpdatePanel ID="ErrorUpdatePanel" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DataSourceMappingGridView" EventName="OnRowCommand" />
</Triggers>
<ContentTemplate>
<asp:LinkButton ID="ErrorTextLinkButton" CommandName="Errors" CommandArgument='<%#Bind("Index") %>' runat="server" Text='View Errors' />
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
But I get the following error:
Could not find an event named 'OnRowCommand' on associated control
'DataSourceMappingGridView' for the trigger in UpdatePanel
'ErrorUpdatePanel'.
The event is called RowCommand not OnRowCommand
Replace
EventName="OnRowCommand"
with
EventName="RowCommand"
and it should work
An event bound to a DropDownList in a standalone GridView obviously would work in this fashion , but things are bit more complicated in this scenario.
The event does not fire for the DropDownList. What's interesting is the event bound to the Button Does fire. Not sure what the difference would be between the DropDownList and TextBox.
I've tried both OnSelectedIndexChanged and OnTextChanged - neither work.
The nesting is as follows:
GridView A
Ajax Accordion
GridView B (With DropDownList)
<AjaxToolkit:AccordionPane ID="AccordionPane1" runat="server">
<Header>
</Header>
<Content>
<asp:GridView runat="server" ID="gv" AutoGenerateColumns="false"
BorderWidth="0" AlternatingRowStyle-BorderStyle="None" ShowFooter="true">
<Columns>
<asp:TemplateField HeaderText="Id">
<ItemTemplate>
<asp:Label runat="server" ID="lblId" Text='<%# Eval("Id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label runat="server" ID="lblType"></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList runat="server" ID="ddlType" OnTextChanged="ddlType_SelectedIndexChanged"
AutoPostBack="true">
</asp:DropDownList>
<asp:Button runat="server" ID="btnTest" OnClick="btnTest_Click" Text="TEST" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</Content>
Thank you!
UPDATE
Turns out this had nothing to do with the nested GridViews or Accordion.
After adding the following, the event now successfully fires:
if (!Page.IsPostBack)
Populate(object);
Turns out this had nothing to do with the nested GridViews or Accordion.
After adding the following, the event now successfully fires:
if (!Page.IsPostBack)
Populate(obj);
I have one page which is placed in the Master Page.
In the master page I have 1 dropdown and one GridView, dropdown is display the category, based on the dropdown list selection it will display the list of videos in the Grid.
In the content page I have the video player, in the page load it will play the video by default.
But when I choose the drop down list which is available in the master page, the page is refreshing, SO the video is start play from the first.
The content page should not refresh, So the video will continuously play.
How can I stop the page refresh in the content page?
All are in master page.
`<asp:UpdatePanel ID="up1" runat="server" UpdateMode="Conditional">
<asp:DropDownList ID="drp_Channel" Width="220px" CssClass="ddl"
AutoPostBack="true" runat="server"
onselectedindexchanged="drp_Channel_SelectedIndexChanged">
<asp:ListItem>-- Select Channels --</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="up2" runat="server" UpdateMode="Conditional">
<asp:GridView ID="grd_Video" runat="server" AutoGenerateColumns="False" OnRowCommand="LinkName"
GridLines="None" ShowHeader="False" Width="100%" EmptyDataText="No Videos Found" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="img_Video" runat="server" BorderColor="#666699" CssClass="imgbox"
ImageUrl='<%#(string)FormatImageUrl((string)Eval("Video_Thumbnail")) %>'
CommandName="imgClick" CommandArgument='<%# Bind("Video_ID")%>'
BorderWidth="0px" Height="40px" ToolTip="Click to view video" Width="50px"
BorderStyle="Double" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnk_VideoName" runat="server" ToolTip="Click to view video"
CommandName="lnkClick" CommandArgument='<%# Bind("Video_ID")%>'
Text='<%# DataBinder.Eval(Container, "DataItem.Video_Name") %>'
CssClass="linkVideo" Width="130px"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<AlternatingRowStyle BackColor="#cccccc" />
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>`
in code behind for binding grid,
DataTable dt1Video = new MDBusiness.MDSUser().GetVideo(intNetId, intChanId, intCatId);
grd_Video.DataSource = dt1Video;
grd_Video.DataBind();
up1.Update();
up2.Update();
Set AutoPostBack = "False" on your dropdownlist to stop the postback from occurring. Users will then be able to change the dropdownlist without anything happening.
You'll need to use AJAX with your dropdownlist if you want to be able to use it without the postback.
for a quick answer
Install ASP.NET AJAX library
Wrap the GridView in a UpdatePanel
Set the trigger to be the DropDownList
Done :)
Remember to see this Screencast... it is exactly what you are after!