How to create a MaskedEditExtender on the fly? - asp.net

I want to create a number of masked edit extenders from codebehind. Something like:
private MaskedEditExtender m_maskedEditExtender;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
m_maskedEditExtender = new MaskedEditExtender()
{
BehaviorID = "clientName"
};
m_maskedEditExtender.Mask = "999999999";
this.Controls.Add(m_maskedEditExtender);
}
protected override void Render(HtmlTextWriter writer)
{
m_maskedEditExtender.RenderControl(writer);
}
When I do this, I get a NullReferenceException on OnLoad of MaskedEditExtender. What is the correct way of doing that? Please note that putting the extender into a repeater-like control and using DataBind does not work for me.
Edit: I do not have an update panel. Turns out I also need to specify a target control on serverside.

See ASP.NET Page Life Cycle Overview if this is in a Page subclass. If you scroll down to the event list, that page advises you to use the PreInit event to create any dynamic controls. It's necessary to do that early to ensure that ASP.NET cleanly loads ViewState at the right stage, among other things.
If you are doing this in a web user control or custom control, though, override CreateChildControls and do this in there.
Post a more complete code example if that doesn't help.

Your example is not providing a TargetControlID.
Do you have an updatePanel on the page? I had problems dynamically creating extenders as they weren't being added to the updatePanel content.
I also think you have to do somethin with the ScriptManager (registering the extender) but I could be mistaken (I don't have access to the code I did dynamic extenders at the moment).

Provide the proper TargetControlID value to MaskedEditExtender

Related

creating Custom FormView

I'm extending the formview class to create a custome formview which has a server control +formview + other server control below it.
the problem is i cant uses
protected override void OnInit(EventArgs e)
{
Parent.Controls.Add(FormViewButtons);
Parent.Controls.Add(this);
Parent.Controls.Add(MessageContainerControl);
}
because i get exception: "The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases.".
any Ideas?
tanks.
You ought to be creating a Composite Custom Control, not extending the FormView.
I don't really understand why should the FormView manipulate the page's controls.
I think you should extend the Page and on this you should do what you want.

How to disable auto data bind of ASP.NET page?

How can I prevent ASP.NET page from automatically binding data controls on the page? I want to increase performance and I want to do binding of each data control based on my own order.
Simple, don't setup data binding on the controls in the designer.
You would then have to bind the controls inside the code behind part of the page with code.
Not quite what the OP asked for but it is also possible to cancel the Select operation on the Datasource control by adding an event handler to the Selecting event.
public void DataSource_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
if (CancelSelect())
{
e.Cancel=true;
return;
}
}

Getting data from child controls loaded programmatically

I've created 2 controls to manipulate a data object: 1 for viewing and another for editing.
On one page I load the "view" UserControl and pass data to it this way:
ViewControl control = (ViewControl)LoadControl("ViewControl.ascx");
control.dataToView = dataObject;
this.container.Controls.Add(control);
That's all fine and inside the control I can grab that data and display it.
Now I'm trying to follow a similar approach for editing. I have a different User Control for this (with some textboxes for editing) to which I pass the original data the same way I did for the view:
EditControl control = (EditControl)LoadControl("EditControl.ascx");
control.dataToEdit = dataObject;
this.container.Controls.Add(control);
Which also works fine.
The problem now is getting to this data. When the user clicks a button I need to fetch the data that was edited and do stuff with it.
What's happening is that because the controls are being added programmatically, the data that the user changed doesn't seem to be accessible anywhere.
Is there a solution for this? Or is this way of trying to keep things separated and possibly re-usable not possible?
Thanks in advance.
Just keep a reference to the control as a variable in the page's code-behind. I.e.
private EditControl control;
protected void Page_Init(object sender, EventArgs e)
{
control = (EditControl)LoadControl("EditControl.ascx");
control.dataToEdit = dataObject;
this.container.Controls.Add(control);
}
protected void Button_Click(object sender, EventArgs e)
{
var dataToEdit = control.dataToEdit;
}
As long as you're creating the control in the right part of the page's lifecycle (Initialization) then ViewState will be maintained. I'm assuming dataToEdit is just a TextBox or something?
Controls created dynamically must be added on Init or PreInit event on the page.
You have to do it here because controls state is not yet loaded. If you add the the control AFTER you'll have them empty since the page already filled control page values early in the page life cycle.
More info about page life cycle here
Here's my solution:
In the page, I keep a reference to the control that is loaded programmatically.
In the control I created a GetData() method that returns an object with the data entered by the user.
When the user submits the form, the page calls the GetData() method on the control to access the data the user entered.

Page unload event in asp.net

Is it possible to call a write a Page_Unload event in code behind similar to Page_Load event? I wanted to call a method on Page Unload. How do I achieve that?
With AutoEventWireup which is turned on by default on a page you can just add methods prepended with **Page_***event* and have ASP.NET connect to the events for you.
In the case of Unload the method signature is:
protected void Page_Unload(object sender, EventArgs e)
For details see the MSDN article.
Refer to the ASP.NET page lifecycle to help find the right event to override. It really depends what you want to do. But yes, there is an unload event.
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
// your code
}
But just remember (from the above link): During the unload stage, the page and its controls have been rendered, so you cannot make further changes to the response stream. If you attempt to call a method such as the Response.Write method, the page will throw an exception.
There is an event Page.Unload. At that moment page is already rendered in HTML and HTML can't be modified. Still, all page objects are available.

ASP.NET AJAX issues when using UserControls

I Have a UserControl called TenantList.ascx which contains a slightly modified GridView from DevExpress (Web.ASPxGridView). This control makes Callbacks without causing a postback which is exactly what I need.
The specific event I need to react on is CustomButtonClicked. I have made my on OnCustomButtonClicked event on the usercontrol TenantList.ascx that fires when the the GridView CustomButtonClicked event fires.
I have an eventhandler on the page where I use the UC. When I debug using VS I can see that I get into the eventhandler as I am suppose to.
My Eventhandler looks like this:
protected void uc_TenantList_CustomButtonCallback(object sender, ASPxGridViewCustomButtonCallbackEventArgs e)
{
Tenant tenant = (Tenant)uc_TenantList.GetGridView().GetRow(e.VisibleIndex);
switch (e.ButtonID)
{
case "btn_show":
ShowRow(tenant);
break;
case "btn_edit":
EditRow(tenant);
break;
case "btn_delete":
DeleteRow(tenant.Id);
break;
default:
break;
}
}
private void EditRow(Tenant tenant)
{
uc_TenantDetails.SetTenantData(cBLL.GetTenant(tenant.Id));
UpdatePanel1.Update();
}
The EditRow function get's called and the UserControl TenantDetails.ascx gets filled with data correctly. However the UpdatePanel1.Update(); is not updating the panel where my TenantDetails UserControl is in.
However if i call UpdatePanel1.Update(); from a normal control registered to the ScriptManager it updates just fine.
protected void Button1_Click(object sender, EventArgs e)
{
uc_TenantDetails.SetTenantData(cBLL.GetTenant(17));
UpdatePanel1.Update();
}
That works without a problem... I am 100% stuck and without any idea of what might be the problem here.
Any suggestion is welcome!!
Cheers
The Real Napster - In real trouble :)
Okay solved this issue
What I needed to do was to enable postback on the gridview control inside my usercontrol.
Then place the Gridview usercontrol in a updatepanel and still keep the details usercontrol in another updatepanel.
That way it all worked out. Not impressed by the solution though. Looks a bit ugly.
Make sure that your update panel is set to always update (not conditionally). You may also find the information in this articles useful:
http://www.asp.net/AJAX/Documentation/Live/overview/PartialPageRenderingOverview.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.update.aspx
The first link will give you some history regarding Partial Page Rendering, the second gives you some more information about the Update method.
From the documentation calling UpdatePanel.Update will cause an update panel to be re-rendered on the client after calling, but only if the UpdatePanel is set to Conditionally update. If it is set to always update this should throw an error.
If your update panel is set to always update, could it be that it is nested in another UpdatePanel which has its update mode set to conditional?

Resources