Access control from .aspx in .ascx - asp.net

I have a custom user control that I made called OrderForm.ascx. I also have an .aspx file that utilizes the OrderForm control.
I want to access a control on the .aspx file from the OrderForm control. Is there a way to do this?

You could use the FindControl method in the user control like this:
Label label = Page.FindControl("Label1") as Label;
if (label != null)
string labelText = label.Text;
As a note on the above, depending on where the Label is in the page, you may need to use recursion to find the Label.
You could also create a property on the page that returns the text of the Label:
public string LabelText
{
get { return Label1.Text; }
}
To access the property from the user control, here are two options:
Option #1
string labelText = ((PageName)Page).LabelText;
Option #2
string labelText = Page.GetType().GetProperty("LabelText").GetValue(Page, null).ToString();

If you have two user controls, ControlA and ControlB, and they are both registered on the same page you can easily access one from the other. Simply create a public property that you want to have access to in ControlB such as:
Public ReadOnly Property ControlB_DDL() As DropDownList
Get
Return Me.ddlItems
End Get
End Property
And then you can reference that property in ControlA after finding that control:
ControlB ctrlB = (ControlB)Page.FindControl("cB");
DropDownList ddl = ctrlB.ControlB_DDL;
Refer here for more info: http://www.dotnetcurry.com/ShowArticle.aspx?ID=155

To access the controls of .ascx in .aspx.
HiddenField selectedEmailsId = performanceReportCtrl.FindControl("CONTROLID") as HiddenField;
And to access controls of aspx in ascx.
HiddenField selectedEmailsId = Page.FindControl("CONTROLID") as HiddenField;

Related

ASP.NET Maintaining ViewState for controls inside a custom control template

I have a template property in my control declared as follows:
<TemplateContainer(GetType(GenericTemplateContainer)),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateInstance(TemplateInstance.Single)>
Property CustomTemplate As ITemplate
In my control's Init event I have the following:
If Me.CustomTemplate IsNot Nothing Then
Dim TemplateContainer As New GenericTemplateContainer
Me.CustomTemplate.InstantiateIn(TemplateContainer)
PlaceHolder.Controls.Add(TemplateContainer)
End If
This allows me to place controls in markup inside my template, but on a post back the controls inside the template are not holding their ViewState.
I have tried adding PersistChildren(True) attribute to CustomTemplate property but I cannot because it's not valid.
Are you putting the values into ViewState? From what I understand, you need to do that. Either that, or re-bind with the data on every postback.
Here's what I like to do inside User Controls. I apologize for this being C# and not VB, but I don't know VB:
public string Text {
get { return (string)ViewState["Text"]; }
set { ViewState["Text"] = value; }
}
Reference: https://weblogs.asp.net/infinitiesloop/Truly-Understanding-Viewstate

Find Control on MasterPage returns nulll

Im trying to access a ModalPopupExtender control and it allways is returning null or object set not set to an intance of an object. I've tried master.Page.FindControl("") and master.FindControl("") and im still not getting the result
MasterPage master = Page.Master as MasterPage;
AjaxControlToolkit.ModalPopupExtender popup = master.Page.FindControl("ModalPopupExtender2") as AjaxControlToolkit.ModalPopupExtender;
Updated: Cannot change the text of my labels in master page
MasterPage master = Page.Master;
AjaxControlToolkit.ModalPopupExtender popup1 = master.FindControl("ModalPopupExtender1") as AjaxControlToolkit.ModalPopupExtender;
Label lblMessage = master.FindControl("lblMessage") as Label;
lblMessage.Text = msg;
Literal ltrlMessage = master.FindControl("ltrlMessage") as Literal;
ltrlMessage.Text = msg;
Label MessageStatus = master.FindControl("lblMessageStatus") as Label;
MessageStatus.Text = msgStatus;
popup1.Show();
you could do
MasterPage master = Page.Master;
If your page is a child of your master page
try this:
AjaxControlToolkit.ModalPopupExtender popup = (AjaxControlToolkit.ModalPopupExtender)Page.Master.FindControl("ModalPopupExtender2");
Regards
Check out this answer. You can have a strongly typed master page, so you don't have to find and then cast the control. The control on the master would be publicly accessible, and the page would know the type of the master page and have it accessible.
EDIT:
the control is not public
Assuming you've set the Master property in your page directive:
<%# Page MasterPageFile="~/MyMaster.master" ...
Odds are, you probably don't need to actually get to the control. Rather, you need to set something in the master page. I'd just use an internal method to do what you need to do:
public partial class MyMaster: MasterPage
{
internal void SetTheFoo(string foo)
{
this.WhateverControl.Text = foo;
}
//etc...
}
Then, from your page, just call it:
Master.SetTheFoo("Foo");
If you still need to get to the control, then in your master page, you could add a public property exposing your modal popup extender.
public AjaxControlToolkit.ModalPopupExtender MyModalPopup
{
get { return this.TheNonPublicModalPopupExtenderControl; }
}

Find control in usercontrol from a Page ASP.NET

I am loading a control to a page dynamically with LoadControl("src to file").
In the usercontrol i have a validator and some other controls that i would like to access from my page. I canät get it to work, null pointer exception.
Scenario is like this. I have a Edit.aspx page which loads the EditTemplate.ascx usercontroll. I would like to get information or find the controls in the EditTemplate from the Edit.aspx site.
I have tried exposing the controls and validators as properties but how do i access them from my Edit.aspx?
Example code:
Edit.aspx, the control is later added into a
Control control = LoadControl("src to ascx");
TemplatePlaceHolder.Controls.Add(control);
EditTemplate.ascx
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="CompanyImageFile" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
CodeBehind
public partial class EditTemplate : System.Web.UI.UserControl, IEditTemplate {
public RequiredFieldValidator Validator {
get { return this.RequiredFieldValidator1; }
set { this.RequiredFieldValidator1 = value; }
}
From the Edit.aspx site i would like to check the validators isValid property. Isvalid is set in a Save method.
The save button that saves the template is located in edit.aspx, so the post in done from that page.
So the question is how to get a hold of the property from the usercontrol in the edit.aspx page, where and how should this be done?
Thanks again.
Easiest way is to have the user control define properties like:
public IValidator SomeValidator {
get { return this.cuvValidator; }
set { this.cuvValidator = value; }
}
public string Text {
get { return this.txtText.Text; }
set { this.txtText.Text = value; }
}
Which your edit page can use.
HTH.
You can always use recursive approach. Check the solution on Steve Smith's blog:
Recursive-FindControl.
As mentioned in previous answers, I would expose any validators you must access from the parent ASPX page as properties in the user control.
public RequiredFieldValidator ValidatorToCheck
{
get { return this.rfvMyField; }
}
Then, you can dynamically add your user control to some placeholder (being sure to assign an ID to the user control).
// In my example, this is occurring in the Page_Load event
Control control = LoadControl("~/Controls/EditTemplate.ascx");
control.ID = "ucEditTemplate";
pnlControlHolder.Controls.Add(control); // the placeholder in my example is a panel
When you want to access the IsValid property on the given validator (presumably in your save action) you can do so as follows (being sure to cast the control to the appropriate type and using the ID you originally assigned to the user control):
EditTemplate control = (EditTemplate)pnlControlHolder.FindControl("ucEditTemplate");
if (control.ValidatorToCheck.IsValid)
{
// Some action
}

How to initialize a ASP.NET User Control With parameter?

For example, I have a user control(ascx) with a label inside,
I will use the the user control in my aspx page.
How can I pass a string value to the ascx page so that it can be display in the label of ascx page at the beginning?
Add this...
public string Whatever
{
get { return label.Text; }
set { label.Text = value; }
}
to your ascx control. Then from the page you are putting it in you can just set the text like... usercontrol.Whatever = "text to display";
or you can use the Whatever as a property on the aspx side of the page.
You can expose whatever controls you want access to in your user control by creating property for them.
In the past when I have had user controls that required certain data for setup I would create an Initialize method which would take in and setup whatever was needed.

Access a content control in C# when using Master Pages

Good day everyone,
I am building a page in ASP.NET, and using Master Pages in the process.
I have a Content Place Holder name "cphBody" in my Master Page, which will contain the body of each Page for which that Master Page is the Master Page.
In the ASP.NET Web page, I have a Content tag (referencing "cphBody") which also contains some controls (buttons, Infragistics controls, etc.), and I want to access these controls in the CodeBehind file. However, I can't do that directly (this.myControl ...), since they are nested in the Content tag.
I found a workaround with the FindControl method.
ContentPlaceHolder contentPlaceHolder = (ContentPlaceHolder) Master.FindControl("cphBody");
ControlType myControl = (ControlType) contentPlaceHolder.FindControl("ControlName");
That works just fine. However, I am suspecting that it's not a very good design. Do you guys know a more elegant way to do so?
Thank you!
Guillaume Gervais.
I try and avoid FindControl unless there is no alternative, and there's usually a neater way.
How about including the path to your master page at the top of your child page
<%# MasterType VirtualPath="~/MasterPages/PublicUI.Master" %>
Which will allow you to directly call code from your master page code behind.
Then from your master page code behind you could make a property return your control, or make a method on the master page get your control etc.
public Label SomethingLabel
{
get { return lblSomething; }
}
//or
public string SomethingText
{
get { return lblSomething.Text; }
set { lblSomething.Text = value; }
}
Refers to a label on the master page
<asp:Label ID="lblSomething" runat="server" />
Usage:
Master.SomethingLabel.Text = "some text";
//or
Master.SomethingText = "some text";
Rick Strahl has a good explanation (and sample code) here - http://www.west-wind.com/Weblog/posts/5127.aspx
Nothing to do different. Just write this code on child page to access the master page label control.
Label lblMessage = new Label();
lblMessage = (Label)Master.FindControl("lblTest");
lblMessage.Text = DropDownList1.SelectedItem.Text;
I use this code for acess to files recursively:
/// <summary>
/// Recursively iterate through the controls collection to find the child controls of the given control
/// including controls inside child controls. Return all the IDs of controls of the given type
/// </summary>
/// <param name="control"></param>
/// <param name="controlType"></param>
/// <returns></returns>
public static List<string> GetChildControlsId(Control control, Type controlType)
{
List<string> FoundControlsIds = new List<string>();
GetChildControlsIdRecursive(FoundControlsIds, control, controlType);
// return the result as a generic list of Controls
return FoundControlsIds;
}
public static List<string> GetChildControlsIdRecursive(List<string> foundControlsIds, Control control, Type controlType)
{
foreach (Control c in control.Controls)
{
if (controlType == null || controlType.IsAssignableFrom(c.GetType()))
{
// check if the control is already in the collection
String FoundControl = foundControlsIds.Find(delegate(string ctrlId) { return ctrlId == c.ID; });
if (String.IsNullOrEmpty(FoundControl))
{
// add this control and all its nested controls
foundControlsIds.Add(c.ID);
}
}
if (c.HasControls())
{
GetChildControlsIdRecursive(foundControlsIds, c, controlType);
}
}
Hi just thought i'd share my solution, found this works for accessing a 'Control' that is inside an < asp:Panel> which is on a 'ContentPage', but from C# code-behind of the 'MasterPage'. Hope it helps some.
add an < asp:Panel> with an ID="PanelWithLabel" and runat="server" to your ContentPage.
inside the Panel, add an < asp:Label> control with ID="MyLabel".
write (or copy / paste the below) a function in your MasterPage Code-behind as follows: (this accesses the label control, inside the Panel, which are both on the ContentPage, from the Master page code-behind and changes its text to be that of a TextBox on the Master page :)
protected void onButton1_click(object sender, EventArgs e)
{
// find a Panel on Content Page and access its controls (Labels, TextBoxes, etc.) from my master page code behind //
System.Web.UI.WebControls.Panel pnl1;
pnl1 = (System.Web.UI.WebControls.Panel)MainContent.FindControl("PanelWithLabel");
if (pnl1 != null)
{
System.Web.UI.WebControls.Label lbl = (System.Web.UI.WebControls.Label)pnl1.FindControl("MyLabel");
lbl.Text = MyMasterPageTextBox.Text;
}
}

Resources