Accessing RepeaterItem Controls in an EventHandler - c#

I have a page with a repeater in it. I'm writing an event handler so that when the user clicks my WebControl button, the event handler for said button iterates through the items in the repeater using FindControl, then uses some of the controls' values. It seems though, that after the page is loaded, the repeater items populate, but when the button is clicked to post this back, as I iterate through the repeater items, I'm seeing that they're all empty. I don't completely understand the sequencing, but I'm assuming it's because my iteration code is trying to access RepeaterItems that haven't been set yet.
The repeater code is in my OnLoad method. Outside of that, I have my event handler trying to iterate through those items after being clicked. This is essentially what I was trying to do:
protected void MyButton_Click(object sender, EventArgs e)
{
foreach(RepeaterItem item in MyRepeater.Items)
{
MyLabel = (Label)item.FindControl("MyLabel");
}
}
The button is located in the FooterTemplate of the repeater.
<asp:Button runat="server" OnClick="SubmitChecklist_Click" cssclass="BlueSubmit" id="SubmitChecklist" text="Submit" />
Thanks in advance.
Edit: To clarify, the exact error I'm getting is NullReferenceException, when I try to do something, for instance, Response.Write(MyLabel.Text)
Edit: After looking into it more today, this is what I understand to be happening: The repeater is databound on postback. When I then make selections from the generated dropdownlists and hit my button, it posts back again. At this point, the repeater is databound again to it's initial values. So, if I must postback in order to get the users' selections, how can I go about this in the button's eventhandler so that I can get the selected values before that repeater gets databound again?

THe problem, it sounds like, is that you may be binding the data to your repeater on load, but not first checking to make sure it isnt a post back.
example:
You request the page. On Load Fires. You bind the data to the repeater.
You maniupulate the data in the reapter then click your button
The page refreshes with the postback, firing the onload event. The data is rebound to your repeater and all previous data entered has been nullified.
the onclick event is triggered and your code tries to retrieve values that no longer exist.
Make sure your databinding code in your onLoad event is nested within an postback check
if (!Page.IsPostBack)
{
Repeater.DataSource = Datatable;
Repeater.DataBind();
}

I've seen the same thing. I don't understand why, but the data doesn't actually get bound until after all events have fired. I ended up making my data source available at the class level and then indexing.
private DataTable myTable;
protected void Page_Load(object sender, EventArgs e)
{
//populate dataTable
if (!IsPostBack)
{
//databind to repeater
}
}
protected void Submit_Click(object sender, EventArgs e)
{
foreach (RepeaterItem item in repeater1.Items)
{
DataRow row = myTable.Rows[item.ItemIndex];
}
}
Ideal? Certainly not but it works.

Instead of relying on the IsPostBack in my OnLoad, I just seperated all of the different states by putting the databinding of the repeater inside of an event handler after the user selects the first option, rather than relying on the IsPostBack of OnLoad. It was a bit convoluted, but I think I'm doing it the right way this time.

Related

ASP.NET listbox selectedValue in PageLoad

I have a problem with listbox. I would like to fill it with data and select Value (listbox.SelctedValue), using postback, after textbox is filled and Page.Validate() is fired. I try to use it in Page_Load. Everything works fine until I dont mark another user. It goes back to the the first one. I know its because I mark the first one again and again it in Page_Load, but how can I mark user after postback in other place? I cant use any buttons.
To be more clear, I have one text box, which causes postback after user put text there. After that I would like to check if Page.Isvalid and is yes, add that user to listbox (which also causes postbacks) and mark him. Without any buttons. How can I do it only once, using autopostback, not every PageLoad ?
Try this
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
if (Page.IsValid)
{
//Mylistbox.SelctedValue = set Your Selected Value
}
}
}

Changing ViewState after event requires additional refresh

I have an Asp:ListBox with OnSelectedIndexChange="OnSIC" and AutoPostback="true".
I want to keep track of the selected index after the postback to show some data that depends on the index.
My idea is to save the selected index in ViewState.
protected void OnSIC(object sender, EventArgs e)
{
ViewState["idx"] = listBox.SelectedIndex;
}
However, after the page is refreshed, Page_Load does not yet have the updated ViewState["idx"] value. An additional refresh is required to make Page_Load get the new index value.
I understand that postback events happen after Page_Load, so I tried moving the code that gets ViewState["idx"] in Page_PreRender, but I get the same behavior.
How can I correctly store the listbox's selected index value, after a OnSelectedIndexChanged event is fired, and use it on the very next page refresh (that happens because of the event postback)?

Checkbox and page reload

I have an asp.net CheckBox, now I want to reload page after check or uncheck and use CheckBox.Checked information to choose sql query for gridview. I have put code like this in Page_Load method:
if (CheckBox1.Checked)
{
query = "select ...";
}
But nothing happen. I set AutoPostBack also. Tried to use event. Don;t know how this system works:/
EDIT:
Checkbox works ok, but the problem is in something different. After I click checkbox, in Page_Load method I will use my query to setup SqlDataSource. Looks like page is reloaded, but gridview is not refreshed. When i click on gridview's column mame (to sort this column), gridview is refreshed by new sql query. So i need to think how to refresh grid view after click check box.
It seems that you are not using IsPostBack property on page load event. If you not use this your CheckBox will be reset on every page load
Try this way
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Here do your stuff.
}
}

Gridview Rowcommand event firing but show hide controls including Gridview not happening

Here is what I am trying to do in two simple steps:
1) New Row (trNewPost) which has table inside and controls in it to add new post or to update existing post.
Default Visible=false;
2) Add Button to make above row visible = true;
3) trMyPosts has Gridview in it and displays all the posts.
Default visible = true.
When user click on editing any row of the gridview (RowCommand event) I just want to hide this grid (trMyPosts) and show trNewPost.
That's all. events firing, but nothing happening.
I think you've got viewstate problem.
One of the things you can do is this :
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// do things here
}
}
Because whenever anything happens, the page posts back. By encapsulating your Page_Load with ! Page.IsPostBack, you prevent those things from happening over and over again.
Now, if your variable is a global variable, you will have this same problem. Consider instead using a Session variable.
Also, I just wanted to show you this piece of code just in case :
protected void HideShowClicked(object sender, EventArgs e)
{
// toggle the visibility of the control
// (that is, if visible then hide, if hidden then show)
myControl.Visible = ! myControl.Visible;
}

ListBox not getting selected items

I have a ListBox which I am adding ListItems to in a codebehind. The problem I'm having is the ListBox is not seeing the selected items. I have the ListBox being populated dynamically depending on what the user selects from a DropDownList, so the DropDownList has AutoPostBack set to true. I think this is somehow causing the problem.
My SelectedIndexChanged method, which is used whenever an item in the DropDownList is selected, calls a method called PopulateListBox. Here's what those methods looks like:
protected void SelectedIndexChanged(object sender, EventArgs e)
{
string typeStr = type.SelectedItem.Text;
MyType = Api.GetType(typeStr);
PopulateListBox();
}
private void PopulateListBox()
{
listbox.Items.Clear();
foreach (PropertyInfo info in MyType.GetProperties())
listbox.Items.Add(new ListItem(info.Name));
}
For what it's worth, here are the DropDownList and ListBox:
<asp:DropDownList runat="server" ID="type" width="281px" OnSelectedIndexChanged="SelectedIndexChanged" AutoPostBack="true" />
<asp:ListBox runat="server" ID="listbox" width="281px" height="200px" selectionmode="Multiple" />
What I am trying to do is add a List of strings (strings being the selected items) as a session variable upon clicking a submit button. The button redirects to a new page after the List has been added to the session. Going through in debugger, the List of strings is empty at the point where I add it to the session.
listbox.GetSelectedIndices() returns nothing.
Update
I can access the selected items if I do not make a change in the DropDownList. The ListBox is initially populated on page load, and if I make selections they are recognized. If I select something from the DropDownList and the ListBox is repopulated, the selections are not recognized.
My Page_Load method does only two things. It initializes my Api variable and calls PopulateDropDown, which looks like this:
private void PopulateDropDown()
{
foreach (Type t in Api.GetAllTypes())
type.Items.Add(new ListItem(t.Name));
string typeStr = type.Items[0].Text;
Type = Api.GetType(typeStr);
PopulateListBox();
}
The problem is that you call PopulateDropDown() on every single Page_Load(), which calls PopulateListBox(), which clears the listbox and repopulates it. By clearing the listbox, you clear the selection.
You need to replace your call to PopulateDropDown() in the Page_Load() with the following code. The issue that I think you don't realize is that the page is loaded on every postback -- and that in the page life cycle, the page load occurs before the event. So by selecting a drop down item, you execute the Page_Load() event first (which indirectly executes the LoadListBox method, clearing the selection). The following code will populate the drop down list the first time the page loads only. Keep it the same wherever else you are using the load dropdown method:
protected void Page_Load(object sender, EventArgs e)
{
// Do your API code here unless you want it to occur only the first
// time the page loads, in which case put it in the IF statement below.
if (!IsPostBack)
{
PopulateDropDown();
}
}
The IsPostBack returns a boolean indicating whether the server side code is running because the page is loading for the first time ("false") or as a post back ("true").
As I said elsewhere, keep in mind that a listbox with potential for multiple selected values must be handled differently than one with potential for a single selection. Don't reference listbox.SelectedItem, but rather:
foreach (ListItem item in lbFullNames)
{
if (item.Selected)
{
// TODO: Whatever you are doing with a selected item.
}
}
I have also found that if you disable the ListBox server-side, then use client side code to enable the list box using code like the following, then you cannot get the selected items server side.
$('.css-class-assigned-to-listbox').attr('disabled', '');
The fix is simply to make sure it is enabled server-side (the default), then disable it (see blow) or enable it (see above) using client-side code.
$('.css-class-assigned-to-listbox').attr('disabled', 'disabled');

Categories

Resources