Binding for user controls embedded in page - asp.net

I have an ASP.NET page where I call this.DataBind() to bind the controls. I also have various user controls embedded. One has a drop down list, the bind statement gets called for it 2x but the sender the first time is not the drop down list.
Am I using the databind incorrectly? I use databind to get the properties of my page bound to a datasource so that I can use those properties in the declarative code.
In my DropDownList, I added if (sender == dropDownList) which solved the problem

Make sure that none of your user controls are themselves calling .DataBind()
.

Related

How to Populate ListBox without PostBack in ASP .NET?

My Web Form consists of two Listboxes lstbx01 and lstbx02. lstbx01 is databound to sqlDataSource01 and it Populates on Page Load Event. lstbx02 is set to populate when the selected value of lstbx01 is passed as a Parameter to sqlDataSource02. Everything works fine if lstbx01 has its AutoPostBack property set to True.
I do not want the page to be Refreshed. I want to set the lstbx02 to populate without page being PostBack.
I have tried the below mentioned Code:
Protected Sub lstbx02_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstbx02.SelectedIndexChanged
lstbx02.DataSource = sqlDataSource02
lstbx02.DataBind()
End Sub
This doesn't help.
I do not think that what you are asking would be possible in WebForms. The code you provided would require a postback to transmit the event back to the server so it can be handled.
Is there a specific reason you cannot do a postback? A possible workaround would be to use AngularJS, Knockout, or some other JS framework to populate inputs on the page. You would then need an event handler that either used AJAX to fetch the relevant data or displayed data that has been cached into the page as JSON.

Call Dynamic Control's Event if exists

The scenario:
I have some JSON data which I'm using to load stored-data into fields on my form. One of these fields is a DropDownList. The DropDownList happens to be in a child, of a child ASCX control, which I'm accessing from a parent ASPX page. When this DropDownList has its SelectedIndexChanged, it makes other fields visible on the form.
I'm using one of my functions to find this control, which is working successfully, but when setting the SelectedValue of my DropDownList control, the SelectedIndexChanged event is not firing. Meaning some fields aren't loading, resulting in some JSON data not being loaded and lost.
I have seen a suggestion of simply calling ddl_SelectedIndexChange(sender, args) function, but the page I'm calling dynamically loads hundreds of child controls depending on the current request, so was wondering if there is a way of invoking the SelectedIndexChanged event (if it exists) for a control, without having to search and manually call the ddl_SelectedIndexChanged() function. Is it possible?
DirectCast(WebUtils.ControlFinder(upMain, f.fieldClientID), DropDownList).SelectedValue = f.fieldData.ToUpper()
I hope it makes sense. Sorry if I haven't made this clear enough.
I ended up using Reflection to Invoke the properties event that I required, worked a treat.

Save the checked status of a CheckBox included inside an ASP ListView

I know there are similar questions about this issue (for example, here and here) but no one results helpful for my problem.
I have a ListView control showing all the users registered in the database and there is a CheckBox for each user shown if the user is approved or not, and I wanna save the changes directly when the CheckBox's Checked property changes.
I know it's not correct to add the event handler on the ListView_ItemDataBound, because after the CheckBox's AutoPostback there is not a new binding, thus the event handler get lost. On the other hand, I can't append the method directly on the ASPX file because this way I can't know which user is affected by the change (at least, I think I can't).
Any sugestion?
Thanks a lot
You have a couple of options.
It's possible that the ListView.ItemCommand event might fire. I'm not sure, though, because the documentation just specifies buttons. You might want to experiment.
The other option would be to harness the ListView.ItemCreated command. I believe that this always runs, regardless of whether the ListView is bound or not, because the item always has to be created, even if it's from ViewState. What you would do in the event handler for that event would be to attach an event handler to the CheckBox Click or CheckChanged event (I forget what the server-side name is for a CheckBox state change event).
So i ran into the same problem. i'm curious, on your page load are you checking if its a postback?
if(!Post.IsPostBack){
//normal page load
}
If you don't have that check, it will call your page load logic, in my case it was resetting the checkbox everytime with my data object.
On the aspx on the checkbox OnCheckedChanged="ckbNameOfCheckbox_CheckedChanged" AutoPostBack="true"
In the code behind
Protected Sub ckbNameOfCheckbox_CheckedChanged(sender As Object, e As EventArgs)
Dim chkBox As CheckBox = CType(sender, CheckBox)
' Gets the item that contains the CheckBox object.
Dim item As ListViewDataItem = CType(chkBox.Parent, ListViewDataItem)
NameOfTheListView.UpdateItem(item.DisplayIndex, sender.Checked)
End Sub

How to update page data after event handling?

On Page_Init I create a table of dynamically created controls based on a couple of database tables. One of the controls is an ImageButton for moving an list item up the list. What this event handler does is to update the SortOrder column in the database for the affected items.
Now the problem is that since the controls are created in the Page_Init event and the SortOrder is updated later on when the ImageButton command event is fired. What's the best procedure for updating the table with the correct SortOrder. If I recreate the table after the event has fired the ImageButton command event does not work any more.
Should I implement a method for updating the data in the table without recreating it?
Should I reload the page in code after the event has fired?
What's your preferred way for solving this problem?
Page events such as Init and Load will always fire before the event handler that raised the postback. This is the basis of the Page lifecycle (For a visual representation by Peter Bromberg, see here). Most developers new to ASP.NET have a major problem understanding and appropriately handling this "quandary".
The ideal way to do this is:
a. Your Page_Init should call a procedure (let's call it BindData() for illustration) that handles the creation of the table based on database data. This method would be similar to a binding method that binds to the database data and renders UI elements on the basis of that binding. IOW, you should remove the table creation code from the Page_Init method and put it in a separate method so that it can be called when needed.
Important note: This BindData() method also handles the attaching of the eventhandler for the dynamically created ImageButton control to the control. We'll call this ImageButton_Click. This is crucial for the control to the event to fire on subsequent postback.
b. When your ImageButton_Click method executes, it calls the BindData() method to recreate the table and it's bindings but with new sort order rules.
So, the order of execution on first load is:
Page_Init
BindData()
The order of execution on subsequent loads (on postback) is:
Page_Init
BindData() - Eventhandler for ImageButton attached.
ImageButton_Click
BindData()
You'll need something like this...
OnInit (IsPostBack = false)
Dynamically create ImageButton
Wireup ImageButton Event Handler
Load Table - Check for a sort-order in Session/Variable. If none; use the default
Click the button
OnInit (IsPostBack = true / 1st Postback)
Dynamically re-create ImageButton
Wireup ImageButton Event Handler
Load Table - with default sort order
ImageButton_OnClick (Still the same 1st postback)
Reload Table - with specific sort order
Save this sort-order variable in Viewstate/Session variable
Cause some other Postback
OnInit (IsPostBack = true / 2nd & Subsequent Postbacks)
Dynamically create ImageButton
Wireup ImageButton Event Handler
Load Table - Check for a sort-order in Session/Variable. If FOUND, use that.
Firstly, you seem to be binding your data manually to UI controls. In Asp.Net there and many ways to avoid this using built-in data binding techniques. Many controls like the GridView allow automatic creation of Html tables from a given data source. There are many other options including Repeaters.
However you do choose to bind your data, the technique is to rebind at some point every time through the page lifecycle.
You need to...
Bind you data on first page load with the default sort order
Rebind the data in the image button’s event handler after the sort order has been changed.
The code would look something like this...
private void Page_Load (...)
{
if (!IsPostBack)
//On First Load
BindData(defaultSoortOrder);
else
BindData(currentSortOrder);
}
private void ImageButton_Click (...)
{
currentSortOrder = newSortOrder;
BindData(currentSortOrder);
}
If the Image button is clicked, you will end up calling BindData twice. But this is necessary since a page postback could be initiated from any control, you need to always ensure you bind the data when the page loads.

How does Databind consume a DataReader

If I have a control on a page that has its Datasource set to a DataReader, does that control consume the reader at the time the Datasource is set, or does the datareader continue to exist until Databind has been executed?
What actually happens under the covers when Databind is executed?
Depending on the Control, DataBind() will Bind the Data to the
Control. It does this by Iterating through the DataSource and create
the Html and other Controls that are needed.
For a DropDownList, DataBind() will create the ListItem for each
record in a DataSet or each Element in an ArrayList.
Later the Render method is call on the DropDownList, which returns the
Html for a Select tag. It also creates the Html for each ListItem by
returning Option tags inside the Select tag.
For a Label, DataBind() will set the Text to the value you pulled from
the Database (for example).
If you don't call DataBind() for the specific control, you can also
make sure that your DataSource is set for a control and call
Page.DataBind(). This will go through the Controls in the Page and
call all of the DataBinds for each Control.
It should be consumed at the time DataBind is executed.
What is the control doing with the datareader during databind? Does it copy it into its internal structures and dispose of the datareader then render?
If I have 10 controls on a page and set the datasource on each to a different datareader, then called page.databind, will the datareaders exist the entire time (from the point of creation until the point where the page.databind completes it's processing)?

Resources