Information disappears on button click - asp.net

I have a ListView that has a FileUpload control and a button in each ListViewItem.
I have an OnClick event on my button where i try and pull information from the FileUpload control, but when I try to access the control all of the values that were set are gone (FileName etc).
What do I need to do differently here to access the information I just entered?
<asp:ListView ID="lv_Uploads" runat="server" OnItemDataBound="GetThumbs" EnableViewState="true" >
<LayoutTemplate>
<div id="itemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<div style="width:500px;>
<asp:FileUpload runat="server" ID="fu_Upload" />
<asp:Button ID="btn_Save" runat="server" Text="Save File" OnClick="SaveFile" />
<br />
</div>
</ItemTemplate>
</asp:ListView>
Code behind:
protected void SaveFile(object sender, EventArgs e)
{
//This always evaluates to an empty string...
string myFile = ((FileUpload)((Button)sender).Parent.FindControl("fu_Upload")).FileName;
}

I tested the code you provided for the aspx and the following as the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lv_Uploads.DataSource = data;
lv_Uploads.DataBind();
}
}
protected void SaveFile(object sender, EventArgs e)
{
//This always evaluates to an empty string...
string myFile = ((FileUpload)((Button)sender).Parent.FindControl("fu_Upload")).FileName;
}
protected void GetThumbs(object sender, ListViewItemEventArgs e)
{
}
protected IEnumerable<string> data = new string[] { "test1", "test2", "test3" };
The FileUpload control had data for me on PostBack.
Are you using an UpdatePanel around the ListView? FileUpload controls are not compatible with UpdatePanels.
See:
FileUpload control inside an UpdatePanel without refreshing the whole page?
and
http://msdn.microsoft.com/en-us/library/bb386454.aspx#UpdatePanelCompatibleControls

Is the ListView control being rebound before SaveFile is fired on PostBack? If so, it would wipe out any values the user entered.

Related

button OnItemCommand not firing inside asp:Repeater

I have a web forms project where i have the following button wrapped in an asp:Repeater
<asp:Repeater ID="rptBookingSlots" OnItemCommand="BookingSlotOnItemCommand" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:Button ID="Button3" CssClass="Delete" CommandName="delete" CommandArgument="<%# (Container.DataItem as RemoveGroup).Id %>" runat="server" Text="Delete" OnClientClick="return confirm('Are you sure you want to permanently delete this record);" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
But when I select the button via the front end it never hits the method I have specified in my code behind
protected void BookingSlotOnItemCommand(object source, RepeaterCommandEventArgs e)
{
switch (e.CommandName)
{
case "delete": //do work to delete record
}
}
I have a page_preRender method which is always hit on the post pack
protected void Page_PreRender(object sender, EventArgs e)
{
if (IsPostBack && !_dataBound)
{
BindAllData();
}
}
Can anyone explain why my onItemCommand method wont get hit when im attached to the process, i am unable to delete records?
Thanks
The way I would do this would be to load the data in the page_load rather than the pre_render.
I have tested this and the button command is stepped into
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var myList = new List<string> {"foo", "bar"};
rptBookingSlots.DataSource = myList;
rptBookingSlots.DataBind();
}
}

Repeater with Buttons doesn't fire OnItemCommand even when DataBind doesn't happen when IsPostBack is true

I've got an image button in a Repeater, which is in a User Control, and I can't get the OnItemCommand event to fire when I click it. It always gives the error: "... Invalid postback or callback argument. Event validation is enabled using ..."
When I change the image button to a link button, it doesn't give me the error, but it still doesn't fire the OnItemCommand function.
I found some other relevant answers (such as How to process events from Buttons inside Repeaters? And what's this EnableEventValidation thing?) but they all say, "Make sure you're data-binding your repeater inside of a if(!Page.IsPostBack) block." I have done that, but it didn't make a difference.
Here's the markup for the repeater:
<asp:Repeater ID="rptExpenses" OnItemDataBound="rptExpenses_ItemDataBound" OnItemCommand="Button_Command" runat="server" >
<ItemTemplate>
<asp:ImageButton ID="ibDelete" ImageUrl="~/Images/delete.png" CommandName="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
Here's some exerpts from the code-behind
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void rptExpenses_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem)) {
var ibDelete = (ImageButton)e.Item.FindControl("ibDelete");
ibDelete.CommandArgument = e.Item.DataItem.ToString();
}
}
protected void Button_Command(object sender, EventArgs e) {
var btn = (IButtonControl)sender;
switch (btn.CommandName) {
case "Delete":
//delete it
break;
}
}
Try using this code instead:
<asp:Repeater ID="rptExpenses" runat="server">
<ItemTemplate>
<asp:ImageButton ID="ibRemove" ImageUrl="~/Images/delete.png" runat="server"
CommandName="Remove"
CommandArgument='<%# Container.DataItem %>'
OnCommand="ibRemove_Click"/>
</ItemTemplate>
</asp:Repeater>
And this in the code behind:
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void ibRemove_Click(object sender, CommandEventArgs e)
{
var btn = (IButtonControl)sender;
switch (btn.CommandName)
{
case "Remove":
//delete it, use btn.CommandArgument to find id to remove
break;
}
}
If you still receive the ... Invalid postback or callback argument. Event validation is enabled using ... error, it most likely means that you are somewhere re-binding the repeater before the ibRemove_Click(...) event is raised.
I found the reason why this was happening in the answer to this question: Why ItemCommand doesn't fired on My Repeater
Turns out that for some reason the Page's DataBind function was invalidating the repeater's controls without passing through the repeater's OnItemDataBound function a second time.

C# - Event handler for dynamic buttons

I have a textbox and submit button created using the design mode.
When the submit button is pressed, it will retrieve the user input from the textbox and then make a query to my database.
It will then display a list of dynamic buttons according to the information retrieved from my database.
However, the event handler for the buttons does not fire when clicked. I guess my problem is the postback but I cannot create those buttons in page_load etc. because I need to get the user input (from the textbox when submit button is pressed) before i can load the buttons.
How can i solve this problem?
Thank you.
Edit (codes):
protected void subBtn_Click(object sender, EventArgs e)
{
//database setup codes
.......
while (reader.Read())
{
Button detailsBtn = new Button();
detailsBtn.Text = reader["fName"].ToString();
//doesn't fire
detailsBtn.Click += new EventHandler(detailsBtn_Click);
memPanel.Controls.Add(detailsBtn);
}
}
Main problem is Postback regenerate dynamic controls on each postback if those controls does not exists.
For quick demo see this code
ASPX CODE
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:Panel ID="pnl" runat="server"></asp:Panel>
</form>
ASPX.CS CODE
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
{
generate();
}
}
public void generate()
{
if (!pnl.HasControls())
{
for (int i = 0; i < 4; i++)
{
Button detailsBtn = new Button();
detailsBtn.Text = "fName" + i.ToString();
detailsBtn.ID = i.ToString();
detailsBtn.Click += new EventHandler(detailsBtn_Click);
pnl.Controls.Add(detailsBtn);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
generate();
}
protected void detailsBtn_Click(object sender, EventArgs e)
{
}
Sound to me like you could easily refactor your page to use a simple <asp:Repeater runat="server" ..></asp:Repeater> instead of dynamically adding controls to a Panel.
Here is a very simple complete sample:
RepeaterTest.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<asp:TextBox ID="theTextBox" runat="server"></asp:TextBox>
<asp:Button ID="theButton" runat="server" OnClick="theButton_Click" Text="Click me" />
<asp:Repeater ID="test" runat="server">
<ItemTemplate>
<asp:Button ID="theRepeaterButton" runat="server" Text='<%# Eval("fName") %>' OnClick="theRepeaterButton_Click" />
</ItemTemplate>
</asp:Repeater>
</asp:Content>
RepeaterTest.aspx.cs
public partial class RepeaterTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void theButton_Click(object sender, EventArgs e)
{
string filter = theTextBox.Text;
// below row simulates fetching data using the filter text in the text box
var data = Enumerable.Range(0, 20).Select(i => new { fName = filter + " " + i });
test.DataSource = data;
test.DataBind();
}
protected void theRepeaterButton_Click(object sender, EventArgs e)
{
var button = (Button)sender;
// do something here based on text/commandname/commandargument etc of the button
}
}

View state on dropdown control

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" UseSubmitBehavior="false"
OnClick="Button1_Click" OnClientClick="this.disabled = true; this.value = 'Submitting...'; "
Text="Click Me…" /></div>
<asp:DropDownList ID = "dListFruits" runat ="server" EnableViewState ="true"></asp:DropDownList>
protected void Page_Load(object sender, EventArgs e)
{
ArrayList aList = new ArrayList();
aList.Add("Apples");
aList.Add("Oranges");
if (!Page.IsPostBack)
{
dListFruits.DataSource = aList;
dListFruits.DataBind();
TextBox1.Text = "Hi";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
}
When i had a break point in a button click event , this peice of statement "dListFruits.DataSource" shows null while debugging. I thought view state will be applied before load event triggered. But when i see the page items are appended into the dropdown list. So view state will be applied just before render?
Just check out the Items collection of the dropdownlist. Viewstate stores the items collection of dropdownlist control.

Setting viewstate on postback

I am trying to set a ViewState-variable when a button is pressed, but it only works the second time I click the button. Here is the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
lblInfo.InnerText = String.Format("Hello {0} at {1}!", YourName, DateTime.Now.ToLongTimeString());
}
}
private string YourName
{
get { return (string)ViewState["YourName"]; }
set { ViewState["YourName"] = value; }
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
YourName = txtName.Text;
}
Is there something I am missing? Here is the form-part of the design-file, very basic just as a POC:
<form id="form1" runat="server">
<div>
Enter your name: <asp:TextBox runat="server" ID="txtName"></asp:TextBox>
<asp:Button runat="server" ID="btnSubmit" Text="OK" onclick="btnSubmit_Click" />
<hr />
<label id="lblInfo" runat="server"></label>
</div>
</form>
PS: The sample is very simplified, "use txtName.Text instead of ViewState" is not the correct answer, I need the info to be in ViewState.
Page_Load fires before btnSubmit_Click.
If you want to do something after your postback events have fired use Page_PreRender.
//this will work because YourName has now been set by the click event
protected void Page_PreRender(object sender, EventArgs e)
{
if (Page.IsPostBack)
lblInfo.InnerText = String.Format("Hello {0} at {1}!", YourName, DateTime.Now.ToLongTimeString());
}
The basic order goes:
Page init fires (init cannot access ViewState)
ViewState is read
Page load fires
Any events fire
PreRender fires
Page renders

Resources