Adding Controls to Control Collection from an update panel - asp.net

Following these two threads:
How can I create an Array of Controls in C#.NET?
Cannot Access the Controls inside an UpdatePanel
I current have this:
ControlCollection[] currentControlsInUpdatePanel = new ControlCollection[upForm.Controls.Count];
foreach (Control ctl in ((UpdatePanel)upForm).ContentTemplateContainer.Controls)
{
currentControlsInUpdatePanel.
}
currentControlsInUpdatePanel does not have an add or insert method. why does the first link i post allow that user to .add to his collection. This is what I want to do, find all the controls in my upForm update panel. but i dont see how i can add it to my collection of controls.

I don't think this code makes sense. You are creating an array of ControlCollection objects and trying to store Control objects in it. Furthermore, since currentControlsInUpdatePanel object is an array, there will not be an Add() method available on that object.
If you want to use the Add() method, try creating currentControlsInUpdatePanel as a List object.
Example:
List<Control> currentControlsInUpdatePanel = new List<Control>();
foreach(Control ctl in ((UpdatePanel)upForm).ContentTemplateContainer.Controls)
{
currentControlsInUpdatePanel.Add(ctl);
}
If you want to continue to use an array to store the Control objects, you will need to use the index value to set your objects in the array.
Example:
Control[] currentControlsInUpdatePanel = new Control[((UpdatePanel)upForm).ContentTemplateContainer.Controls.Count];
for(int i = 0; i < upForm.Controls.Count; i++)
{
currentControlsInUpdatePanel[i] = ((UpdatePanel)upForm).ContentTemplateContainer.Controls[i];
}

The UpdatePanel's child controls collection is a special collection that contains only one child control: its template container. It is then that control that contains all the child controls of the UpdatePanel (such as a GridView or Button).
As it is noted in the other questions linked to in the question, walking the child control tree recursively is the best way to go. Then, when you've found the spot to which you need to add controls, call Controls.Add() in that place.
My suggestion would be a different approach: place an <asp:PlaceHolder> control in the UpdatePanel and give it a name and add controls to that. There should be no particular advantage to accessing the controls collection of the UpdatePanel itself, and then you wouldn't have to dig through implementation details of the controls (which, while they are unlikely to change, can make code much more difficult to read).

Try to use
ControlCollection collection = ((UpdatePanel)upForm).ContentTemplateContainer.Controls;
This gives you all the controls in that control collection. From there you can use CopyTo to copy it to the array you need:
Control[] controls = new Control[collection.Length];
collection.CopyTo(controls , 0);

Related

How do I reference a repeater (or other object) from a public function?

I have an ASP.NET 4.0 (VB) application with a bunch of repeaters spread throughout several pages and user controls. I am trying to create a single public function that I can call to databind and paginate whichever repeater I specify, but am having difficulties referencing the repeater object from within that public function so that the function will know which repeater , on which page, is calling it. Is there a way to do this or is my underlying method flawed?
Pass in any control you need to manipulate ByRef as a parameter into your function (ex = Page, Repeater, etc). If you're performing different logic for each repeater/page it seems silly to make an all encompassing function to handle it. If most repeaters follow the same code path in your function or something in your function must be called on all of those repeaters, then it makes sense to follow this model.

How to bind to a control within an ASP.NET ListView

I have a list that I need to bind to a List I get from an API. The list looks like this:
struct DataItem { int level; string name; Guid key };
List<DataItem> myList = API.GetList();
ListView1.DataSource = myList;
ListView1.DataBind();
All this works fine for display. However, the table must edit the level value. I am unsure how to make that happen. I have tried event handlers on the listView, but they are never called. I have tried a text box for the level field (with both Bind and Eval) and an event handler OnTextChanged, but the event handler is never called. (I have tried with various combiniations of AutoPostBack and ViewState enabled.)
How can I programatically edit this data structure?
Two way data binding you are trying to implement here won't work like this - List doesn't implement INotifyPropertyChanged (someone correct me if I'm wrong).
You may consider using a plain old DataTable which can be two-way-bound out-of-the-box. If performance is not a highly critical issue, converting your List to a DataTable (and back, depending on what you want to do with the modified data) is simple enough, rather than struggling with custom implementations of list types.

Populate a user control from a containing frame

I have a troubling task. I have a page contained within an outer frame, on the outer frame is a user control which i need to populate with some data from within the containing page. The problem is the outer frame is rendered before i can get hold of the required data. How can i accomplish this?
I would use a JavaScript to accomplish this. You can put a Populate method in JavaScript in the parent page with whatever signature you want.
function PopulateControls(param1, param2, param3)
{
document.getElementById('<%=this.Control1.ClientID%>');.value = param1;
document.getElementById('<%=this.Control2.ClientID%>');.value = param2;
document.getElementById('<%=this.Control3.ClientID%>');.value = param3;
}
Then in the child frame, make sure the page has a built in JavaScript to pass it back up.
window.onload=SendToParent;
function SendToParent()
{
window.opener.PopulateControls('<%=this.Field1.ClientID%>','<%=this.Field2.ClientID%>',<%=this.Field3.ClientID%>');
}
You might have to tweak the code above, but the gist is that the parent page controls will end up waiting until the child page is fully loaded before it's done. If you want to use labels and whatnot, you can use the InnerHTML property on divs instead.
Couldn't you just create a public Populate sub in your user control and call it from the outer frame when required data is loaded? Populate would take the data as arguments and populate the control with this data.

in asp.net avoid rebinding of data to grid on every pageload

in asp.net suggest me a best way for storing and binding datatable to grid to avoid rebinding on each pageload
thanks
Grid values will be stored in ViewState automatically. You shouldn't need to be rebinding on every postback unless you're changing the data.
If you have a dataset that you're retrieving different "views" from each time, like custom paging or sorting, then you should evaluate using the Cache to store your dataset.
If viewstate is enable then you do not need to rebind.
If something is changing and you need to rebind you have a couple of options. Store your datasource in the viewstate or session. Then you don't need to hit the database each time you need to add a filter or paginate etc.
Eg.
// Load up date initially
public void LoadYourData()
{
// This gets your data however you are doing it, in this example I am returning
// a list of objects.
List<YourObjects> yourData = GetYourData();
// You then have the option to save it in the session or viewstate, I will
// demonstrate both. Make sure if you are using viewstate that your objects are
// serializable. You should probably also create helper classes to deal with
// getting and setting data from the ViewState object or Session.
Session["YourData"] = yourData;
ViewState["YourData"] = yourData;
}
// Then make a bind function that gets the data out of whatever store you have it in
public void BindYourGrid()
{
// I will assume you used session
grdYourGrid.DataSource = (List<YourObjects>)(Session["YourData"]);
grdYourGrid.DataBind();
}
So when you need to use it in your Page_Load you could just use the following:
GetYourData();
BindYourGrid();
If you need to apply something a filter you just need to pull the data out of your store (session or viewstate) and perform your manipulation and store it again. Then just call BindYourGrid();.
This way you are never actually hitting the DB unless you need to. There are other methods for caching your datasource's data as well and they all have pros and cons. Go with whatever works in your case though as I have only shown two methods.

Best Practise to Define and update MXML component in Flex application

A Flex components values are initialized by init method.
In an application flow,
How to refresh a mxml component data value ; as init is called at the start up itself only.
Example of mxml component may be
as simple as button label or text
as complex as repeater whose data provider is a web service
( means a fresh quesy should be made to pull the data and refresh the dataprovider of repeater )
If the dataprovider is a collection or an array it will update itself as items are added to or deleted from the collection. You can listen to the CollectionEvent.CollectionChange event to see when a collection changes.
I'm not really sure what you mean though? Are you on about binding?
If you want to re-init the whole control, you could create an "reset" event and have the handler for the reset execute the same behavior as the init code.
That's the best I can do without more details...
you should create yourself setters and getters for the properties you want to modify and a refresh is required afterwards. for example:
private var _tmp : String = '';
public function set tmp(val : String) : void {
this._tmp = val;
this.doOtherDataRefreshNeeded();
}
public function get tmp() : String {
return this._tmp;
}
and this way, everytime the code that uses this component and needs to update it's tmp property. the setter will be called and in there a lot of other stuff can happen beside assigning the value.
for simple mxml components as texts and inputs, use bindings {} for their data values. those should update as soon as the data changes. if not, call .invalidateNow() method on them to force update.
use ValidateNow() method in mxml component in updating method

Resources