Aspx and Ascx lifecycles : avoid multiple select on database - asp.net

I use an ascx user control for manage CRUD o database entity. I reuse this userc control in my aspx page for show in readonly mode the database data of a record on database. The user control have inside a simple FormView and an objectdatasource.
Now, in a aspx page that contains that ascx i have to know, in DATABIND time of the aspx some data of the record of the database that is considerate by the user control. User control are databind after the aspx page, and for this reason i don't have the data. I have to do a select in aspx page on database and after the user control do the same select.
How can i do for optimize this process?

ASCX base events may be fired after your ASPX's base events, but in the whole lifecycle, you can fire your own events.
You could define an Event on your ASCX, make your page register to this event, and then propagate your custom event from your ASCX to your ASPX, with whatever data you need in the arguments
rough example (may not compile) : in the ASCX
public partial YourControl : System.Web.UI.UserControl {
public event EventHandler MyControlDataBound;
public void FireMyControlDataBound()
{
if (MyControlDataBound!= null)
{
MyControlDataBound(this, new EventArgs());
}
}
protected void MyDataBound(object sender, EventArgs e) {
// ......
FireMyControlDataBound();
}
}
and in the ASPX
public partial class MyPage: Page
{
protected void Page_Load(object sender, EventArgs e)
{
yourUserControlInstance.MyControlDataBound += HandleYourDataInYourPage;
}
protected void HandleYourDataInYourPage(object sender, EventArgs e) {
// .. do whatever needed in your page, with your data
// if you have defined a custom Args class that inherits EventArgs, your could collect data here...
}
}
Feel free to create a class that inherits EventArgs to pass data with your event if you need this

You can pass your arguments to your UserContol in init event of your Page
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var control = (UserControl)this.FindControl("UserControlId");
control.Property = ...;//Pass User Control properties
}

Related

How to use Load and Unload events in a user web control?

I swear to god I tried googling it.
I have a webcontrol that logs into the database the time and date of a page load, and same of page unload.
I can't set it up to save my life.
can somebody provide a solution?
Thanks!
You can use UserControl's Load and Unload events.
public partial class WebUserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
// Log to Database
}
protected void Page_Unload(object sender, EventArgs e)
{
// Log to Database
}
}
Here is ASP.Net Page Life Cycle
The page fires the load event, which recursively goes through all of its controls, including your user control, to fire that load event on it. same action occurs for Unload. The page controls it all, which is controlled by the module that controls the ASP.NET framework.

How to put working buttons in a databound control

If I make my own custom control, I have to make sure I add all controls in the OnInit, or else postbacks won't work. ProcessPostData is called between Init() and Load(), so if I add my controls in Load(), the post data step has already been done before my control was on the page.
However, if I put a button in an ASP.NET repeater and only bind data to the repeater in Page_Load(), the repeater triggers the ItemCommand event, even though the control was not on the page during Init. How does this work? How do I make my own custom control that adds buttons to the control in Load() or PreRender()?
I want something like this:
public class WrappedButton : WebControl
{
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
var button = new Button { Text = "Hello" };
button.Click += SomeCommand;
Controls.Add(button);
}
private void SomeCommand(object sender, EventArgs e)
{
Page.Response.Write("This won't get executed");
}
}

Access textbox value in a header in a master page to .aspx.vb page

I created a textbox and a submit button in header(User Control) included in a master page
and I want to use that textbox value after clicking submit in my .aspx.vb page.
How can i access that, as the vb page is loaded first and then master page is loading ?
TextBox Val = (TextBox)this.Master.FindControl("TextBoxID");
The best way to communicate from UserControl to Page/MasterPage is using events
The best way to communicate from MasterPage to Page is using events
On this way you don't hardlink UserControls with their Pages/MasterPages and the Page with it's Master.
Add an event to your UserControl that is raised when the user clicks the button, for example:
In UserControl of type MyControl:
public delegate void SubmittedHandler(MyControl ctrl);
public event SubmittedHandler Submitted;
protected void BtnCLick(object sender, EventArgs e) {
Submitted(this);
}
Then add an handler to this event in your MasterPage, handle it and raise the Master's event again:
In Master's codebehind:
public delegate void MyControlSubmittedHandler(MyControl ctrl);
public event MyControlSubmittedHandler ControlSubmitted;
protected void Page_Init(Object sender, EventArgs e) {
this.MyControl1.Submitted += MyControlSubmitted;
}
protected void MyControlSubmitted(MyControl sender) {
ControlSubmitted(sender);
}
Then add an handler to this event to your page:
In your Page:
protected void Page_Init(object sender, EventArgs e) {
((SiteMaster)Master).ControlSubmitted += MasterControlSubmitted;
}
protected void MasterControlSubmitted(MyControl sender){
// do whatever you need to do
}
If you only need to access the TextBox from the page and you don't need to handle the click-event, you could also use properties to achieve this:
add a public property f.e. MyControlText in your UserControl that get/set the TextBox.Text property
add a public property f.e. MyControlText in your Master that get/set your UserControl's MyControlText property
Now you can get/set this property from your page in this way:
((SiteMaster)Master).MyControlText = "Hello World";

ASP.NET Custom user control to add dynamically

I have hard time to modify a page that had a Custom User Control directly to the ASPX page and now require to have it dynamically loaded when needed only. The User Control does have html and other controls via the ASCX file and has code in the code-behind.
I have read multiple page and have found that I cannot instantiate directly the User Control but should use the Page.LoadControl(...). The problem is not the compiling but when the page load the control it happen that all controls inside the ASCX are null and then crash.
How can I use a User Control that has code in the ASCX and in the code-behind dynamically?
Edit:
Example of what I am doing in (PageLoad or PagePreRender or PagePreInit)
Control c = LoadControl(typeof(MyControl), null);
myControl= (MyControl)c;
myControl.ID = "123";
myControl.Visible = false;
Controls.Add(myControl);
MyControl does have for example <div id="whatever" runat="server">... and inside the MyControl it set the visibility to True or False... but when it does that, now it crash because the "whatever" div is NULL.
What I have done is use the Page.LoadControl method in the Page_Init to add the custom user control to a place holder on the page.
protected void Page_Init(object sender, EventArgs e)
{
//MyControl is the Custom User Control with a code behind file
MyControl myControl = (MyControl)Page.LoadControl("~/MyControl.ascx");
//UserControlHolder is a place holder on the aspx page
// where I want to load the user control to
UserControlHolder.Controls.Add(myControl);
}
This works fine for me.
Here is the code for the dynamically loaded user control:
MyControl.ascx.cs
public partial class MyControl : System.Web.UI.UserControl
{
protected void Page_Init(object sender, EventArgs e)
{
LiteralControl lit = new LiteralControl("Test Literal Control");
Page.Controls.Add(lit);
}
protected void Page_Load(object sender, EventArgs e)
{
whatever.Visible = true;
if (IsPostBack)
{
whatever.Visible = false;
}
}
}

Accessing Events And Members In The Master Page

I have an event in the Master page that I want to access in the pages that use that master page but it doesn't seem to be working.
In the Master
public delegate void NotifyRequest(object sender, EventArgs e);
public class MyMaster
{
public event NotifyRequest NewRequest;
protected void uiBtnNewTask_Click(object sender, EventArgs e)
{
if(NewRequest!= null)
NewRequest(this, e)
}
}
Inherited Page
MyMaster mm = new MyyMaster();
mm.NewRequest += new NotifyRequest(mm_NotifyRequest);
void mm_NotifyRequest(object sender, EventArgs e)
{
Label1.Text = "Wow";
this.Label1.Visible = true;
}
My problem is the event is always null. Any ideas?
You probably need to use the following syntax to access your event in the Master Page
((MyMaster)Master).NewRequest += new NotifyRequest(mm_NotifyRequest);
If you wish to access members of a master page you need to use the page Master attribute and cast it to your master page.
Alternately
If you wish do not wish to use a cast you can use the #MasterType directive to create a strong reference to your master page, in this case MyMaster. So you would be able to access your event like so: Master.NewRequest.
More Reading about Master Pages

Resources