calling a method on the parent page from a user control - c#

I am using a user control that I created (just a .cs file not an .ascx file), that does some magic and depending on a value generated by the control, I need it to do something on the parent page that is 'hosting' the control. It needs to call a method under certain circumstances (method is on the parent control).
the control is placed on the parent page like so:
<customtag:MyControl ID="something" runat="server" />
I'm dynamically creating buttons etc on the control itself but when a button is clicked, let's say for example that there's a text box on the control and if the value of the textbox is "bob" it needs to call a method on the page that's housing the control...how can I accomplish this?

You could do what casperOne suggested, but I wouldn't advise it. This is tightly coupling your user control to your parent page, which kind of defeats the purpose of a user control.
Personally, I'd add an event to the user control (say, ButtonClicked) that the parent page can handle. In the event handler in your parent, deal with the event however you see fit. This way you can plug the user control into a different page at a later date and not have to worry about logic in the user control that requires a specific kind of parent page.

You should be able to get the Page hosting the control through the Parent property. However, that's going to be returned to you as a Control. You have to cast it to the type of your page in order to access any methods on the page which you have defined.

I think that casperOne is on the right track, but you need to go a step further. I'm giong to make the assumption that this user control will be used on more then on page. (I normally write VB.Net, sorry if my C# is malformed)
Make a base page class (you can store it in your App_Code directory or in a project):
public class PageToInheritFrom : System.Web.UI.Page {
public void SpecialFunction() {
}
}
Now make sure that all of your pages inherit from this page in your code behind file:
public partial class _Default : PageToInheritFrom {
}
Now in your user control you know what the page type is and can call
((PageToInheritFrom)this.Page).SpecialFunction();

Related

Accessing Template items of UserControl

Is it possible to implement custom UserControl or Control, which will act like a PlaceHolder, but with my logic? Example of using:
<x:MyControl runat="server">
<Template>
<asp:TextBox runat="server" ID="MyTextBox" />
..... any custom code here ........
</Template>
</x:MyControl>
And then in code-behind:
MyTextBox.Text = "ABC";
I implemented test control, but I am unable to access nested ASP controls on the page level. Error is The name "MyTextBox" does not exist in the current context.
You must call the function "FindControl" in you user control MyControl.
Name you MyControl with and id="mcContainer", then on your code behind call ((TextBox)mcContainer.FindControl("MyTextBox")).Text = "ABC";.
Wiki about this here How to: Create Templated ASP.NET User Controls
Why can I write MyTextBox.Text="ABC" when it is in the Page and why isn't that possible when the text box is inside of naming container implemented by a user control?
Well, when you drag N dropped your text box the ASP.NET Page designer declared a variable for you in the partial class of your page reserved for the designer itself, is in that designer part of your class that your controls in you page are declared.
So when you drag and drop your user control, and create a text box inside of it's naming container you can't access it directly because your page doesn't hold a reference to that control, the reason for that is because that control will only be available at runtime during the instanciation of the user control itself, the motive is related in part with the way that ASP.NET page parser renders controls.
Quoting this resource:
When working with composite controls it is important to be familiar with a number of properties and methods, as well as with the INamingContainer interface. All composite controls should implement the INamingContainer interface. Controls that implement this interface do not need to add any methods or properties; rather, the implemented interface merely indicates that the control is being used as a composite control. The effect is that child controls—that is, controls in the composite control's Controls collection—are rendered so that their ID is prefixed with the ID of the control's naming container. This ensures that all the child controls will have unique ID values, even if there are multiple instances of the parent control on a Form. The WebControl class has a NamingContainer property that returns the control's parent.
So, when you write MyTextBox, your text box name should at least something like $mcContainer$MyTextBox. So because of this there is no way to transparently do what you intend.
Solution.
Create class like this:
public class ToolTip : PlaceHolder
{
protected override void CreateChildControls()
{
HtmlGenericControl div1 = new HtmlGenericControl("div");
div1.Attributes.Add("id", ClientID);
div1.Attributes.Add("class", "tooltip");
while (Controls.Count != 0)
div1.Controls.Add(Controls[0]);
Controls.Add(div1);
}
}
Then register it in ASPX file like this:
<%# Register Assembly="YOUR_ASSEMBLY" TagPrefix="x" Namespace="YOUR_NAMESPACE" %>
Then use it like this:
<x:ToolTip runat="server">
... any your content here ......
</x:ToolTip>
Now you are able to nest any controls inside of x:ToolTip and add any composition logic to CreateChildControls().

How to call user control's(.ascx) method in .aspx page

I have created user control, in that user control i have one method and I want to call this method in .aspx. I have registered this user control in aspx
For example:
Below is method in user control.
public void SetGridData()
{
}
I want to call above method in .aspx.cs file.
How can we call this method?
Somewhere in the ASPX page's code you should have a reference to the user control object. For example, if the user control is called MyUserControl then somewhere at the class level for the page (possibly in a separate partial class designer file) should be:
protected MyUserControl myUserControl1;
or something similar to that. That's the instance of the user control for the page's class. The page life cycle should instantiate it by the time Page_Load is reached, so from then on you can use that object:
myUserControl1.SetGridData();
If this is purely an example, then you can call methods in codefiles with the following syntax:
<%= SetGridData(); %>
However, just be aware of the notes I put in the comments above.

Access Controls from UserControls in ASPX page

How to Access Controls from UserControls in ASPX page?
For example:
I want to access gridview which is in usercontrol on ASPX page.
Please help me.
Try this :
GridView GridView1 = (GridView)WebUserControl1.FindControl("GridView1");
Where WebUserControl1 is ID of use control on .aspx page.
Hope this helps..
The best way is to provide properties in your UserControl that you can access.
For example:
public GridView UserGrid
{
get
{
return GridView1;
}
}
But the question is why you need this.
Rule of thumb: Only expose as few as possible. On that way your code will be most robust and readable. So it would e.g. better to expose it's DataSource rather than the complete GridView.
On the other hand, if you want your page to react on events in your UserControl, it should provide custom events(e.g. UserDeleted) that your page then can handle.
Page-UserControl-Commmunication
Because the controls now nothing about eachother at the same level, you have to use the parent page to get it. Try this logic:
Create a property referring to your parent page (the page your control usually is in (might be different because of layering of controls)
Create a property on your page referring to the usercontrol the grid is in, or link to that grid directly.
page.aspx
public UserControl UserGridControl
{
get;
set;
}
userControl.ascx
public Page ParentPage
{
get;
set;
}
Example call:
Instantiate the properties first. After that, use the following statement to access anything from that control (as an example I used Foo() here, to use as a dummy method, but it seems it was unclear to someone):
otherControl.ascx:
this.ParentPage.UserGridControl.Foo();
EDIT: Want to have a direct code example to be able do it from the page only? See Tim Schmelters answer. If you need a way to call the grid from another user control as well. Use mine.

Changing displayed data from a static method in ASP.NET

I have two user controls that sit on a page which determines which should be displayed. The user controls generate some html that is passed into an asp:literal and subsequently manipulated via javascript. It is done this way due to the lack of a suitable control that I am allowed to use on the project.
When a user clicks a view change button, a WebMethod is called on the main page (the one that holds the controls) from the control's javascript. From here, a static method on the control is called. The control then needs to regenerate the html and place it into the asp:literal for the view change to be complete.
My problem is that I am in a static method on the control's page, and have no access to the non-static genorateHtml function. I have tried a singleton pattern with no success (this could have been due to improper implementation). Any ideas on how to make this call? THANKS!
I used to hit similar issues at with one of the projects i worked on. The solution we ended up adopting was implementation of System.Web.UI.ICallbackEventHandler with partial rendering to return just the needed content depending on arguments. ICallbackEventHandler runs in the page lifecycle.
The only trouble we had then was performance issues relative to implementation which posts back the whole form instead of just the arguments you want.
Maybe the best way for you would be through this method in which they render the control from a static method. That would probably suit your needs.
Hope this helps!

ASP.Net: User control with content area, it's clearly possible but I need some details

I have seen two suggestions for my original question about whether it is possible to define a content area inside a user control and there are some helpful suggestions i.e.
Passing in content to ASP.NET user control
and
ASP.NET User Control inner content
Now, I like the theory of the latter better than the former just for aesthetic reasons. It seems to make more sense to me but the example given uses two variables content and templateContent that the answerer has not defined in their example code. Without these details I have found that the example does not work. I guess they are properties of the control? Or some such?
EDIT - DETAILS: What I am trying to do
I have need of an ASP.Net user control that conceals some content in a panel inside a placeholder and asks for the input of a code in a visible panel.
Essentially the user will put their code into the provided textbox in Panel A and submit it, it will be checked and, if it is valid, panel B and the locked content will be displayed.
I have done a test where the content was hard coded into panel B but as soon as I need to make the content a generic input it fails. If it were just text or somesuch then I could make it a property of the control, but as it is, in fact, another User Control I am having some difficulty getting this into the "hidden" panel.
Any other workable solutions are also welcome.
EDIT NOTE: The solution I'm trying to implement this in 2.0 I did find a 3.5 solution which I cannot use.
The former example seems workable but I'd prefer to go with the latter if someone could fill in the blanks for me.
Thanks.
Okay, so this is disturbingly easy but many of the tutorials on the web that talk about this kind of thing push to do extravagant things that require the control to parse ListItems or such.
So this solution is purely so that you can build a control that, for whatever reason, has a placeholder in it that could have anything inside it (kind of like a content area on a Master page). In this instance it happens to be because the Panel containing the placeholder is hidden until appropriate input actions have taken place in another panel.
First, you need to add this:
[ParseChildren(true,"Content")]
[PersistChildren(false)]
just above the part of the control which looks like this:
public partial class MyControl : System.Web.UI.UserControl
then in the control scoped declarations at the head of the control you want to declare thus:
private Control _content;
[PersistenceMode(PersistenceMode.InnerProperty)]
public Control Content { get { return _content; } set { _content = value; } }
Finally you need to place the content into the placeholder like this:
phContent.Controls.Add((Control)_content);
That last line goes into the Page_Init event. For reference "phContent" is the name of the place holder where you want the content to appear, like this:
<asp:Panel ID="pnlLockable" runat="server" Visible="False">
<asp:Placeholder runat="server" ID="phContent" />
</asp:Panel>
On the front end the resulting implementation looks like this:
<uc:MyControl runat="server" ID="lockit1">
<Content>
//...your stuff goes here...
</Content>
<uc:MyControl>
Note that I presume that what is inbetween the Content Tags is a root control. This is because I nested another user control in there. I imagine if you put whatever content you want within a panel or placeholder it should be fine.
Also you can read "How to: Create Templated ASP.NET User Controls". Really helpful.

Categories

Resources